Tutorial: Make escrow transactions

In this tutorial, you create an invoice between users using tokens for a transaction with escrow.

Allow about 15 minutes to complete this tutorial.

In an escrow transaction, payment is received from the buyer by an escrow agent who is not part of the transaction. The escrow agent holds the payment until the conditions of the sale have been met. For example, the satisfactory delivery of a product or service. When the conditions of sale have been met, the escrow agent delivers the payment to the seller.

As such, unlike a standard transaction, an escrow transaction requires an extra step before moving payment from the payer to the recipient to allow for fulfillment of the escrow terms. This tutorial demonstrates how Tilia services can act as an escrow agent and support escrow transactions.

The following diagram shows a successful escrow transaction process.

User to user escrow transaction flow

API operations in this tutorial

Tutorial interaction API operations used Scope
Create a user-to-user escrow transaction Create an escrow transaction write_invoices
Pay user-to-user escrow transaction Pay an escrow transaction write_invoices
Commit escrow transaction Commit an escrow transaction write_invoices
Cancel escrow transaction Cancel an escrow transaction write_invoices

To complete this tutorial

This tutorial uses the Explore Tilia transactions collection from the shared Postman workspace.

To complete this tutorial successfully:

  1. Make sure the software described in Get started with the tutorials has been installed on your system and configured.
  2. Make sure that you have initialized the Tilia Client Info environment variables by running the User account tutorials .
  3. In Postman:
    1. Open the Tilia tutorial workspace you created in Get started with the tutorials for this tutorial.
    2. Make sure you have the Explore Tilia transactions collection forked to your Tilia tutorial workspace .
    3. Make sure that you've selected the Tilia Client Info environment and confirmed that it has:
      1. Your Tilia developer credentials.
      2. All of the user-related environment variables with Current values defined.
    4. In your Tilia tutorial workspace , open the list of Collections .
    5. In the list of Collections , expand the Explore Tilia transactions collection.
    6. If it's been more than an hour since you last got an access token for this collection, get a new one as described in Tutorial: Transactions overview , and then return to continue here.

Create a user-to-user escrow invoice

This exercise creates a user-to-user invoice with an escrow requirement.

The tutorial starts after collecting the necessary information about the users who are participating in the transaction. That information can be combined with the line-items to create the invoice.

Creating an invoice starts with collecting all the required information, and then sending it to Tilia to create the complete invoice. The data is assembled into the following object to send in the request body.

An escrow invoice needs the following information:

  • A summary description of the invoice
  • The product information
  • payer's account_id : from the paying user's account information
  • source_wallet_id : the wallet ID of the payer's wallet. If omitted, the default wallet for the account_id is used.
  • destination_account_id : the recipient's account ID, retrieved from the recipient or catalog. If this property is used, the default wallet is used. If destination_account_id is used, destination_wallet_id can be omitted.
  • destination_wallet_id : the recipient's wallet to receive the tokens from the sale. This is the value used in this exercise. If destination_wallet_id is used, destination_account_id can be omitted.

This information is then collected in the following object to send in the request body to create the escrow invoice.

Copy
Copied
{
  "account_id": "{{payers_account_id}}",
  "description": "Digital product order with escrow",
  "line_items": [
    {
      "amount": 350000,
      "currency": "TIL",
      "transaction_type": "user_to_user",
      "description": "In-game digital bundle w/escrow",
      "recipients": [
        {
          "source_wallet_id": "{{payers_wallet_id}}",
          "destination_wallet_id": "{{recipients_wallet_id}}"
        }
      ]
    }
  ]
}

To send this information and create a new user-to-user escrow transaction, in Postman:

  1. In the Explore Tilia transactions collection, in the Escrow transaction - completed folder, open the Create a user-to-user escrow transaction request.
  2. In the request Body tab, notice that it has the information described previously.
  3. In the Create a user-to-user escrow transaction request, choose Send .
  4. After the response returns, open the response Body tab below the request to review the response body details.
Show a typical response body with the transaction details.
Copy
Copied
{
    "status": "Success",
    "message": [],
    "codes": [],
    "payload": {
        "id": "esc_2ZHRweUDyUY2PW2vCuKtSExL3uH",
        "account_id": "acct_2Ym84qq2ieeaZkOHUM1xeF8uJtu",
        "escrow_invoice_id": "d6627cf1-32eb-4695-8bef-b748e34758fa",
        "commit_invoice_id": "",
        "cancel_invoice_id": "",
        "status": "OPEN",
        "integrator": "tilia-test",
        "created": "2023-12-08T23:14:17Z",
        "updated": "2023-12-08T23:14:17Z",
        "escrow_invoice": {
            "invoice_id": "d6627cf1-32eb-4695-8bef-b748e34758fa",
            "integrator": "tilia-test",
            "account_id": "acct_2Ym84qq2ieeaZkOHUM1xeF8uJtu",
            "invoice_type": "user_purchase_escrow_virtual",
            "reference_type": "",
            "reference_id": "",
            "transfer_id": "",
            "session_id": "",
            "state": "OPEN",
            "description": "Digital product order with escrow",
            "failure_code": "",
            "failure_reason": "",
            "created": "2023-12-08T23:14:17Z",
            "updated": "2023-12-08T23:14:17Z",
            "payment_methods": {
                "41a64965-f990-4323-8781-ec56c5e365fc": {
                    "payment_method_id": "41a64965-f990-4323-8781-ec56c5e365fc",
                    "payment_method": {
                        "id": "41a64965-f990-4323-8781-ec56c5e365fc",
                        "account_id": "acct_2Ym84qq2ieeaZkOHUM1xeF8uJtu",
                        "method_class": "standard",
                        "display_string": "Standard TIL wallet",
                        "provider": "wallet",
                        "psp_reference": "6e4dc9f9-b3d7-4752-866e-367d9c67b56b",
                        "psp_hash_code": "",
                        "processing_currency": "TIL",
                        "pm_state": "ACTIVE",
                        "integrator": "tilia-test",
                        "created": "2023-11-27 21:06:46",
                        "updated": "2023-11-27 21:06:46",
                        "tags": [
                            {
                                "tag_id": "paytag_2Ym84lpfGISzkfFeQRiKDCmn1uD",
                                "resource_type": "payments.payment_method.id",
                                "resource_id": "41a64965-f990-4323-8781-ec56c5e365fc",
                                "account_id": "acct_2Ym84qq2ieeaZkOHUM1xeF8uJtu",
                                "namespace": "payment_method",
                                "tag": "virtual",
                                "status": "ACTIVE",
                                "integrator": "tilia-test",
                                "created": "2023-11-27T21:06:45.942729Z",
                                "updated": "2023-11-27T21:06:45.942729Z"
                            },
                            {
                                "tag_id": "paytag_2Ym84qFxvdh7m2tNvVIKPps0B03",
                                "resource_type": "payments.payment_method.id",
                                "resource_id": "41a64965-f990-4323-8781-ec56c5e365fc",
                                "account_id": "acct_2Ym84qq2ieeaZkOHUM1xeF8uJtu",
                                "namespace": "payment_method",
                                "tag": "standard",
                                "status": "ACTIVE",
                                "integrator": "tilia-test",
                                "created": "2023-11-27T21:06:45.950864Z",
                                "updated": "2023-11-27T21:06:45.950864Z"
                            }
                        ],
                        "wallet_balance": "10302750",
                        "payment_method_id": "",
                        "provider_data": {
                            "balance": 10302750,
                            "wallet_balance": "10302750",
                            "wallet_id": "6e4dc9f9-b3d7-4752-866e-367d9c67b56b"
                        }
                    },
                    "invoice_id": "d6627cf1-32eb-4695-8bef-b748e34758fa",
                    "payment_id": "",
                    "currency": "TIL",
                    "display_amount": "TIL 350000",
                    "display_string": "Standard TIL wallet",
                    "requested_amount": 350000,
                    "authorized_amount": 350000,
                    "authorized_amount_usd": 3500,
                    "provider": "wallet",
                    "exchange_id": "",
                    "tags": {
                        "standard": {
                            "tag_id": "",
                            "tag": ""
                        }
                    },
                    "created": "2023-12-08T23:14:17Z",
                    "updated": "2023-12-08T23:14:17Z",
                    "subitems": {
                        "12c1c11b-4e8b-4cdc-8447-b59e02bc0f65": {
                            "subitem_id": "12c1c11b-4e8b-4cdc-8447-b59e02bc0f65",
                            "invoice_id": "d6627cf1-32eb-4695-8bef-b748e34758fa",
                            "amount": 0,
                            "amount_usd": 0,
                            "currency": "TIL",
                            "display_amount": "TIL 0",
                            "invoice_reference": "pm_41a64965-f990-4323-8781-ec56c5e365fc",
                            "reference_type": "",
                            "reference_id": "",
                            "subitem_type": "standard_virtual_payment",
                            "source_account_id": "acct_2Ym84qq2ieeaZkOHUM1xeF8uJtu",
                            "source_payment_method_id": "41a64965-f990-4323-8781-ec56c5e365fc",
                            "source_wallet_id": "6e4dc9f9-b3d7-4752-866e-367d9c67b56b",
                            "destination_account_id": "75452177-cad5-42bd-8530-4fb86ecc6fa9",
                            "destination_payment_method_id": "",
                            "destination_wallet_id": "87a494bc-f648-4dcd-b0fc-e59106e0598f",
                            "description": "",
                            "metadata": {
                                "escrow": true,
                                "pm_display_string": "Standard TIL wallet"
                            },
                            "exchange_id": "",
                            "tags": null,
                            "created": "2023-12-08T23:14:17Z",
                            "updated": "2023-12-08T23:14:17Z"
                        }
                    }
                }
            },
            "line_items": {
                "1f4233ef-c570-41f0-b934-cb251b899182": {
                    "line_item_id": "1f4233ef-c570-41f0-b934-cb251b899182",
                    "invoice_id": "d6627cf1-32eb-4695-8bef-b748e34758fa",
                    "amount": 350000,
                    "amount_usd": 3500,
                    "amount_refunded": 0,
                    "currency": "TIL",
                    "display_amount": "TIL 350000",
                    "reference_type": "",
                    "reference_id": "",
                    "transaction_type": "user_to_user_escrow_virtual",
                    "product_sku": "",
                    "product_code": "",
                    "description": "In-game digital bundle w/escrow",
                    "exchange_id": "",
                    "sort_order": 0,
                    "tags": null,
                    "created": "2023-12-08T23:14:17Z",
                    "updated": "2023-12-08T23:14:17Z",
                    "subitems": {
                        "2d225e55-39df-4adc-a251-1e9288a03e68": {
                            "subitem_id": "2d225e55-39df-4adc-a251-1e9288a03e68",
                            "invoice_id": "d6627cf1-32eb-4695-8bef-b748e34758fa",
                            "amount": 350000,
                            "amount_usd": 3500,
                            "currency": "TIL",
                            "display_amount": "TIL 350000",
                            "invoice_reference": "li_1f4233ef-c570-41f0-b934-cb251b899182",
                            "reference_type": "invoicing.invoice_line_item_v2.line_item_id",
                            "reference_id": "1f4233ef-c570-41f0-b934-cb251b899182",
                            "subitem_type": "user_recipient_escrow_virtual",
                            "source_account_id": "75452177-cad5-42bd-8530-4fb86ecc6fa9",
                            "source_payment_method_id": "",
                            "source_wallet_id": "41f5e46b-76ef-4bf8-b661-d5fb30159713",
                            "source_wallet": {
                                "wallet_id": "41f5e46b-76ef-4bf8-b661-d5fb30159713",
                                "description": "tilia-test virtual asset TIL wallet",
                                "account_id": "75452177-cad5-42bd-8530-4fb86ecc6fa9",
                                "currency": "TIL",
                                "current_balance": 1764950,
                                "active": true,
                                "tags": [
                                    "hos",
                                    "virtual_asset",
                                    "virtual",
                                    "negative_balance_allowed"
                                ],
                                "integrator": "tilia-test",
                                "created": "2021-12-10T20:39:26.106346Z",
                                "updated": "2023-12-08T21:45:53.934739Z"
                            },
                            "destination_account_id": "75452177-cad5-42bd-8530-4fb86ecc6fa9",
                            "destination_payment_method_id": "",
                            "destination_wallet_id": "5dac78d0-4864-4c2c-b3c2-9e2d1d3278af",
                            "destination_wallet": {
                                "wallet_id": "5dac78d0-4864-4c2c-b3c2-9e2d1d3278af",
                                "description": "tilia-test virtual escrow TIL wallet",
                                "account_id": "75452177-cad5-42bd-8530-4fb86ecc6fa9",
                                "currency": "TIL",
                                "current_balance": 0,
                                "active": true,
                                "tags": [
                                    "hos",
                                    "virtual_escrow",
                                    "virtual"
                                ],
                                "integrator": "tilia-test",
                                "created": "2021-12-10T20:39:26.106346Z",
                                "updated": "2023-12-04T19:04:23.292372Z"
                            },
                            "description": "",
                            "metadata": {
                                "destination_account_id": "acct_2Ym85jZvz2HNx9q2LuouUymkFz3",
                                "destination_wallet_id": "36dfbb98-2551-40c8-a60c-617e29bdbb48",
                                "escrow": true
                            },
                            "exchange_id": "",
                            "tags": null,
                            "created": "2023-12-08T23:14:17Z",
                            "updated": "2023-12-08T23:14:17Z"
                        },
                        "ff311897-2985-4e11-97ed-ceac95cb91ef": {
                            "subitem_id": "ff311897-2985-4e11-97ed-ceac95cb91ef",
                            "invoice_id": "d6627cf1-32eb-4695-8bef-b748e34758fa",
                            "amount": 350000,
                            "amount_usd": 3500,
                            "currency": "TIL",
                            "display_amount": "TIL 350000",
                            "invoice_reference": "li_1f4233ef-c570-41f0-b934-cb251b899182",
                            "reference_type": "invoicing.invoice_line_item_v2.line_item_id",
                            "reference_id": "1f4233ef-c570-41f0-b934-cb251b899182",
                            "subitem_type": "ar_to_asset",
                            "source_account_id": "75452177-cad5-42bd-8530-4fb86ecc6fa9",
                            "source_payment_method_id": "",
                            "source_wallet_id": "87a494bc-f648-4dcd-b0fc-e59106e0598f",
                            "source_wallet": {
                                "wallet_id": "87a494bc-f648-4dcd-b0fc-e59106e0598f",
                                "description": "tilia-test virtual ar TIL wallet",
                                "account_id": "75452177-cad5-42bd-8530-4fb86ecc6fa9",
                                "currency": "TIL",
                                "current_balance": 0,
                                "active": true,
                                "tags": [
                                    "hos",
                                    "virtual_ar",
                                    "negative_balance_allowed",
                                    "virtual"
                                ],
                                "integrator": "tilia-test",
                                "created": "2021-12-10T20:39:26.106346Z",
                                "updated": "2023-12-08T21:45:53.934739Z"
                            },
                            "destination_account_id": "75452177-cad5-42bd-8530-4fb86ecc6fa9",
                            "destination_payment_method_id": "",
                            "destination_wallet_id": "41f5e46b-76ef-4bf8-b661-d5fb30159713",
                            "destination_wallet": {
                                "wallet_id": "41f5e46b-76ef-4bf8-b661-d5fb30159713",
                                "description": "tilia-test virtual asset TIL wallet",
                                "account_id": "75452177-cad5-42bd-8530-4fb86ecc6fa9",
                                "currency": "TIL",
                                "current_balance": 1764950,
                                "active": true,
                                "tags": [
                                    "hos",
                                    "virtual_asset",
                                    "virtual",
                                    "negative_balance_allowed"
                                ],
                                "integrator": "tilia-test",
                                "created": "2021-12-10T20:39:26.106346Z",
                                "updated": "2023-12-08T21:45:53.934739Z"
                            },
                            "description": "",
                            "metadata": null,
                            "exchange_id": "",
                            "tags": null,
                            "created": "2023-12-08T23:14:17Z",
                            "updated": "2023-12-08T23:14:17Z"
                        }
                    }
                }
            },
            "subitems": {},
            "tags": null,
            "summary": {
                "total_amount": 350000,
                "total_amount_usd": 3500,
                "currency": "TIL",
                "display_amount": "TIL 350000",
                "subtotal": {
                    "total_amount": 350000,
                    "total_amount_usd": 3500,
                    "currency": "TIL",
                    "display_amount": "TIL 350000"
                },
                "tax": {
                    "total_amount": 0,
                    "total_amount_usd": 0,
                    "currency": "TIL",
                    "display_amount": "TIL 0.00"
                },
                "payment_breakdown": [],
                "tax_calculation": ""
            }
        }
    }
}

After creating the transaction, the payload.status value is OPEN. Notice that the invoice data returned in the response body includes many more properties than were sent in the request. For more information about what you can include when creating an invoice, review Create an escrow transaction.

Pay escrow transaction

This exercise pays the transaction created in the previous request.

The preceding task only created an invoice in Tilia's e-commerce system. No tokens have changed accounts, yet. This exercise collects the tokens from the payer and holds them in escrow.

To pay the escrow transaction, in Postman:

  1. In the Explore Tilia transactions collection, in the Escrow transaction - completed folder, open the Pay escrow transaction request.
  2. In the URL field, notice that the invoice_id returned by the preceding request is used to identify the invoice to pay.
  3. In the Pay escrow transaction request, choose Send .
  4. After the response returns, open the response Body tab below the request to review the response body details.
Show a typical response body with the payment details.
Copy
Copied
{
    "status": "Success",
    "message": [],
    "codes": [],
    "payload": {
        "id": "esc_2ZHRweUDyUY2PW2vCuKtSExL3uH",
        "account_id": "acct_2Ym84qq2ieeaZkOHUM1xeF8uJtu",
        "escrow_invoice_id": "d6627cf1-32eb-4695-8bef-b748e34758fa",
        "commit_invoice_id": "",
        "cancel_invoice_id": "",
        "status": "ESCROWED",
        "integrator": "tilia-test",
        "created": "2023-12-08T23:14:17Z",
        "updated": "2023-12-08T23:14:17Z",
        "escrow_invoice": {
            "invoice_id": "",
            "integrator": "",
            "account_id": "",
            "invoice_type": "",
            "reference_type": "",
            "reference_id": "",
            "transfer_id": "",
            "session_id": "",
            "state": "",
            "description": "",
            "failure_code": "",
            "failure_reason": "",
            "created": "",
            "updated": "",
            "payment_methods": null,
            "line_items": null,
            "subitems": null,
            "tags": null,
            "summary": {
                "total_amount": 0,
                "total_amount_usd": 0,
                "currency": "",
                "display_amount": "",
                "subtotal": {
                    "total_amount": 0,
                    "total_amount_usd": 0,
                    "currency": "",
                    "display_amount": ""
                },
                "tax": {
                    "total_amount": 0,
                    "total_amount_usd": 0,
                    "currency": "",
                    "display_amount": ""
                },
                "payment_breakdown": null,
                "tax_calculation": ""
            }
        }
    }
}

The invoice returned in the response buffer shows the current state of the invoice in the value of payload.status, which is now ESCROWED. The tokens from the payer have been collected and are being held in escrow.

Commit escrow transaction

This exercise commits the escrow transaction and pays the recipient.

The preceding exercise collected tokens from the payer to hold them in escrow. This exercise completes the purchase process and transfers the funds to the recipient, which you would do after the escrow conditions have been met.

To commit the escrow transaction, in Postman:

  1. In the Explore Tilia transactions collection, in the Escrow transaction - completed folder, open the Commit escrow transaction request.
  2. In the URL field, notice that the invoice_id returned by the create request is used to identify the invoice to commit.
  3. In the Commit escrow transaction request, choose Send .
  4. After the response returns, open the response Body tab below the request to review the response body details.

A typical response body looks like the following.

Copy
Copied
{
    "status": "Success",
    "message": [],
    "codes": [],
    "payload": {
        "id": "esc_2ZHRweUDyUY2PW2vCuKtSExL3uH",
        "account_id": "acct_2Ym84qq2ieeaZkOHUM1xeF8uJtu",
        "escrow_invoice_id": "d6627cf1-32eb-4695-8bef-b748e34758fa",
        "commit_invoice_id": "323a3574-59d0-44ee-a1f2-084da8c75bf3",
        "cancel_invoice_id": "",
        "status": "COMMITTED",
        "integrator": "tilia-test",
        "created": "2023-12-08T23:14:17Z",
        "updated": "2023-12-08T23:18:34Z"
    }
}

The payload.status value is now COMMITTED showing that the payer has paid the invoice identified in the response buffer and the recipient has received the payment.

Cancel escrow transaction

This exercise demonstrates how to cancel an active, and paid, escrow transaction.

After an escrow transaction has been paid, it can be canceled instead of committed.

The preceding exercises collected tokens from the payer to hold them in escrow until the escrow conditions have been met. If the escrow conditions are not met, this cancels the purchase process, and returns the tokens to the payer.

Create and pay an escrow transaction to cancel

Before an escrow transaction can be canceled, it must be created and paid.

To create a new user-to-user escrow transaction, in Postman:

  1. In the Explore Tilia transactions collection, in the Escrow transaction - canceled folder, open the Create a user-to-user escrow transaction request.
  2. In the request Body tab, notice that it has an object that is similar to that used in the previous exercises.
  3. In the Create a user-to-user escrow transaction request, choose Send .
  4. After the response returns successfully, continue.
  5. In the Explore Tilia transactions collection, in the Escrow transaction - canceled folder, open the Pay escrow transaction request.
  6. In the Pay escrow transaction request, choose Send .
  7. After the response returns successfully, continue.

At this point, you have a paid escrow transaction that can be committed or canceled. Continue to the next exercise to cancel it.

Cancel the paid escrow transaction

To cancel the escrow transaction, in Postman:

  1. In the Explore Tilia transactions collection, in the Escrow transaction - canceled folder, open the Cancel escrow transaction request.
  2. In the URL field, notice that the invoice_id returned by the preceding request is used to identify the invoice to pay.
  3. In the Cancel escrow transactio n request, choose Send .
  4. After the response returns, open the response Body tab below the request to review the response body details.

A typical response body looks like the following.

Copy
Copied
{
    "status": "Success",
    "message": [],
    "codes": [],
    "payload": {
        "id": "esc_2ZHVpXpoNaWxYmBLkk9aNUHgBNp",
        "account_id": "acct_2Ym84qq2ieeaZkOHUM1xeF8uJtu",
        "escrow_invoice_id": "7c93346a-7c02-4bc4-8270-1d461302603b",
        "commit_invoice_id": "",
        "cancel_invoice_id": "7b11217d-265c-4408-b6cb-32f24d3f3934",
        "status": "CANCELLED",
        "integrator": "tilia-test",
        "created": "2023-12-08T23:46:14Z",
        "updated": "2023-12-08T23:46:22Z"
    }
}

The payload.status value is now CANCELLED showing that the invoice identified in the response buffer has been canceled and the tokens have been returned to the payer.

Next steps

The exercises in this tutorial used Postman to call the Tilia APIs. For an example of how to integrate the escrow transaction demonstrated in this tutorial into a web page, see Escrow transaction.

If you're curious, you can review the wallet balances of the users involved in this transaction by using the exercises in the Get info about transactions tutorial.

You can also return to the Transaction tutorials overview and find another transaction tutorial, or just go to the next transaction tutorial.