User-to-Integrator Purchase

A typical purchase transaction consists of collecting payment information, creating an invoice, and submitting the invoice to Tilia Pay for processing. This example explains how to create a transaction for a purchase between you (the integrator) and a user.

Prerequisites

To complete this example, you'll need the following:

  • An Access Token with the requisite scopes: write_user_tokens and write_invoices
  • An account ID for the purchasing user. Refer to Registering Users for information on creating user accounts.
  • A web page containing the Tilia Pay widget script. Refer to Widget Integration for instructions on setting this up.
  • A payment method. Refer to Test Payments for payment methods you can use in testing.
This example assumes you are using the purchase widget. If you are using the redirect method, you will need to adjust the instructions in step 2 accordingly. Refer to Redirect Integration for more information.

The process of creating a transaction involves the following steps:

Step 1: Create a secure redirect URL

Step 2: Call the purchase flow to obtain payment details

Step 3: Set up the purchase transaction

Step 4: POST the invoice for processing

Step 5: Handle the completion event

Step 1: Create a secure redirect URL

To start, you will pass the user's account ID and the required scopes to create a redirect URL. This URL creates a secure user session and forms the basis for calling the Tilia Pay Purchase flow.

This example requires an API token with the scope write_user_tokens.

curl --location --request POST https://auth.tilia-inc.com/authorize/user \
--header 'Authorization: Bearer <Access_Token>' \
--header 'Content-Type: application/json' \

Request Body

Copy
Copied
{
	"account_id": "string",
	"scopes":["user_info","read_payment_method","write_payment_method","read_kyc","verify_kyc"]
}

Sample response

Copy
Copied
{
    "status": "Success",
    "message": [],
    "codes": [],
    "payload": {
        "redirect": "https://web.tilia-inc.com/ui/appauth/ed8ff1e9-9256-4205-918a-b9ca23ec00ec"
    }
}

Included in the response is a redirect URL which is used in the next step.

Step 2: Call the purchase flow to obtain payment details

The Purchase flow is a web UI that allows the user to choose a payment method in the context of a purchase. If the user does not have a stored payment method, they will be able to add one. Upon completion of the flow, an ID for the user's payment method is passed back to you for use in creating the transaction.

Users must have a signed copy of the most recent Tilia Pay Terms of Service (TOS) on file. If the user has not accepted the TOS, or if there is an updated version available, they are presented with a TOS screen which must be accepted before they can select a payment method.

From the widget page, call the following JavaScript to execute the purchase flow.

Copy
Copied
window.Tilia.execute({
	rootId: <your.element.id>,
	flow: purchase,
	redirect: https://web.tilia-inc.com/ui/appauth/ed8ff1e9-9256-4205-918a-b9ca23ec00ec,
	onComplete: handleComplete,
});

The widget invokes the handleComplete callback with the result of the flow.

If the user cancels anywhere in the flow:

Copy
Copied
{
	source: “tilia”,
	event: “tilia.pm.complete”,
	state: “cancel”,
}

If the user completes the flow:

Copy
Copied
{
	source: “tilia”,
	event: “tilia.pm.complete”,
	id: <payment.method.id>,
	psp_reference: <psp.reference>,
	pm_state: <payment.method.state>
}

The value for id is the payment_method_id used in the next step.

Step 3: Set up the purchase transaction

Once you have the user's payment_method_id, you are ready to set up your purchase transaction, in the form of an invoice. Tilia Pay uses the concept of invoices to describe the detailed information required to process a transaction.

For a user-to-integrator purchase, the value for transaction_type must be user_to_integrator.

For this transaction type, you need to provide the following values:

  • account_id - the buyer's account ID
  • payment_method_id - the id returned by the payment flow
  • currency - the currency for the purchase
  • amount - the amount of the purchase

Additionally, you will want to provide details about the item(s) being purchased, including your product description, SKU, and other transaction information.

The following example is for a simple invoice with a single item. More complex invoices, including multi-seller invoices, can be built using various properties found in our invoicing API. Refer to the API reference for details.

This example is in USD. Therefore, all amounts are in cents. Refer to Working with currencies for information on how currencies are used.

This example requires an API token with the scope write_invoices.

curl --location --request POST https://invoicing.tilia-inc.com/v2/invoice \
--header 'Authorization: Bearer <Access_Token>' \
--header 'Content-Type: application/json' \

Request Body

Copy
Copied
{
  "account_id": "<buyer_account_id>",
  "reference_type": "product_purchase_id",
  "reference_id": "purchase_id123",
  "description": "A description of the product",
  "payment_methods": [
    {
      "payment_method_id": "<id_from_payment_flow>"
    }
  ],
  "line_items": [
    {
      "amount": 500,
      "currency": "USD",
      "transaction_type": "user_to_integrator",
      "reference_type": "integrator_product_id",
      "reference_id": "product123"
    }
  ]
}

Sample response

A successful request returns the HTTP 201 Created status code and a JSON response body containing the invoice details. You will use the invoice_id field value in the next step.

Copy
Copied
{
    "status": "Success",
    "message": [],
    "codes": [],
    "payload": {
        "invoice_id": "20fee8d0-4831-4cd9-9640-b8f7a5b1205a",
        "account_id": "793fab8e-6da5-4b26-b7f9-aab9cf809f91",
        "reference_type": "product_purchase_id",
        "reference_id": "purchase_id123",
        "state": "open",
        "description": "A description of the product",
        "metadata": null,
        "summary": {
            "total_amount": 500,
            "currency": "USD",
            "display_amount": "USD 5.00"
        },
        "created": "2020-05-11T15:54:12Z",
        "updated": "2020-05-11T15:54:12Z",
        "payment_methods": {
            "3843d8cd-c99c-4f90-a416-aee2134cc56c": {
                "payment_method_id": "3843d8cd-c99c-4f90-a416-aee2134cc56c",
                "authorized_amount": 500,
                "currency": "USD",
                "display_amount": "USD 5.00",
                "subitems": {}
            }
        },
        "line_items": {
            "b26cfded-128c-4f29-a657-4ce8fed82691": {
                "line_item_id": "b26cfded-128c-4f29-a657-4ce8fed82691",
                "product_sku": "",
                "amount": 500,
                "currency": "USD",
                "display_amount": "USD 5.00",
                "reference_type": "integrator_product_id",
                "reference_id": "product123",
                "transaction_type": "user_to_integrator",
                "description": "",
                "metadata": null,
                "subitems": {}
            }
        },
        "subitems": {}
    }
}

Step 4: Post the invoice for processing

In the previous step, we created the invoice. Next, it needs to be submitted for processing and payment.

To submit the invoice for processing, POST the invoice_id to the /pay endpoint.

curl --location --request POST https://invoicing.tilia-inc.com/v2/invoice/{invoice_id}/pay \
--header 'Authorization: Bearer <Access_Token>' \
--header 'Content-Type: application/json' \

Sample response

A successful request returns the HTTP 200 OK status code and a JSON response body containing the invoice details. Note that the value for state has updated from open to processing.

Copy
Copied
{
    "status": "Success",
    "message": [],
    "codes": [],
    "payload": {
        "invoice_id": "20fee8d0-4831-4cd9-9640-b8f7a5b1205a",
        "account_id": "793fab8e-6da5-4b26-b7f9-aab9cf809f91",
        "reference_type": "product_purchase_id",
        "reference_id": "purchase_id123",
        "state": "processing",
        "description": "A description of the product",
        "metadata": null,
        "summary": {
            "total_amount": 500,
            "currency": "USD",
            "display_amount": "USD 5.00"
        },
        "created": "2020-05-11T15:54:12Z",
        "updated": "2020-05-11T15:54:12Z",
        "payment_methods": {
            "3843d8cd-c99c-4f90-a416-aee2134cc56c": {
                "payment_method_id": "3843d8cd-c99c-4f90-a416-aee2134cc56c",
                "authorized_amount": 500,
                "currency": "USD",
                "display_amount": "USD 5.00",
                "subitems": {}
            }
        },
        "line_items": {
            "b26cfded-128c-4f29-a657-4ce8fed82691": {
                "line_item_id": "b26cfded-128c-4f29-a657-4ce8fed82691",
                "product_sku": "",
                "amount": 500,
                "currency": "USD",
                "display_amount": "USD 5.00",
                "reference_type": "integrator_product_id",
                "reference_id": "product123",
                "transaction_type": "user_to_integrator",
                "description": "",
                "metadata": null,
                "subitems": {}
            }
        },
        "subitems": {}
    }
}

The value for state will be processing until the invoice is processed, at which time the state will update to either:

  • success, indicating the invoice has been successfully paid.
  • failed, indicating the invoice could not be paid. In this case, the failure_reason field returns additional information describing the failure.

You can check the status of an invoice by calling GET https://invoicing.tilia-inc.com/v2/invoice/{invoice_id}.

Step 5: Handle the completion event

Although this step is not mandatory, we recommend implementing a webhook to notify you about changes to the transaction's status.

The webhook request body will be the same as the response body from create or pay invoice, but with a state of success or failed. See the Invoice Completion webhook documentation for complete details.

Currently, webhook endpoints must be configured manually by Tilia staff. We are developing a web interface to enable you to control this directly. For now, please contact us for assistance.