Payment Intents

Learn how and when to use our Payment Intents endpoints for Tilled payments.

Create an integration that can handle complex payment flows by utilizing the Payment Intents API. It follows a payment from creation to checkout and initiates additional authentication steps as needed.

Creating and confirming a PaymentIntent is the first step in developing an integration with the Payment Intents API. Confirming a PaymentIntent indicates that the customer intends to pay using the current or provided payment method. Following confirmation, the PaymentIntent attempts to initiate a payment. In most cases, each PaymentIntent corresponds to a single shopping cart or customer session in your application. The PaymentIntent summarizes transaction details such as the payment methods that are accepted, the amount to be collected, and preferred currency.

PaymentIntent Creation

You must construct the PaymentIntent on your server and provide the client with the client secret. The client confirms the payment, and your server watches webhooks to see if the transaction succeeds or fails.

You can clarify options such as amount and currency once you create the PaymentIntent.

1$ curl -X POST \
2-H "tilled-api-key: {%raw%}{{SECRET_KEY}}{%endraw%}" \
3-H "tilled-account: {%raw%}{{MERCHANT_ACCOUNT_ID}}{%endraw%}" \
4-H "Content-Type: application/json" \
5-d '{ "amount": 1099, "currency": "usd", "payment_method_types": ["card"] }'
The amount is a positive integer representing how much to charge in the smallest currency unit (e.g., 1000 cents to charge $10.00).

PaymentIntent Flow

To help monitor your sales funnel, we recommend developing a PaymentIntent as soon as you know the amount, such as when the customer begins the checkout process. You can change the amount if it changes. For example, if a customer exits the checkout process and adds additional items to their cart, you may need to update the amount when they re-enter the checkout process.

If the checkout process is interrupted and then resumed, try to reuse the same PaymentIntent rather than creating a new one. Each PaymentIntent has a unique ID that can be used to recover it if necessary. To accommodate restoration, you can store the PaymentIntent ID in your application's data model on the customer's shopping cart or session. The advantage of reusing the PaymentIntent object is that it helps track any failed payment attempts for a specific cart or session.

Confirming a PaymentIntent

The API provides a lot of flexibility to handle different workflows, such as being able to add a payment_method_id within Create PaymentIntent. You are also able to confirm at the same time as creation by passing confirm=true in the body. For PaymentIntents that have a status requires_payment_method, you must have a payment method and use the Confirm PaymentIntent API.

You can specify the PaymentIntent id in the path and the payment_method_id in the body:

1$ curl -X POST{%raw%}{{PAYMENT_INTENT_ID}}{%endraw%}/confirm \
2-H "tilled-api-key: {%raw%}{{SECRET_KEY}}{%endraw%}" \
3-H "tilled-account: {%raw%}{{MERCHANT_ACCOUNT_ID}}{%endraw%}" \
4-H "Content-Type: application/json" \
5-d '{ "payment_method_id": "{%raw%}{{PAYMENT_METHOD_ID}}{%endraw%}" }'
To create a payment_method_id see Create a payment method for more details about Tilled.js and API

Status and Lifecycle

Asynchronous payment flows are complex to manage because they depend on customer interactions that happen outside of your application. PaymentIntents simplify this by keeping track of the status of the payment. They act as the single source of truth in the lifecycle of the flow.

  • requires_payment_method
    • When the PaymentIntent is created, it has a status of requires_payment_method until a payment method is attached.
    • We recommend creating the PaymentIntent as soon as you know how much you want to charge, so that Tilled can record all the attempted payments.
    • If the payment fails (for example, due to a decline), the PaymentIntent's status returns to requires_payment_method.
  • requires_confirmation optional
    • After the customer provides their payment information, the PaymentIntent is ready to be confirmed.
    • In most integrations, this state is skipped because the payment method information is submitted at the same time that the payment is confirmed.
  • requires_capture optional
    • Separate authorization and capture to create a charge now, but capture funds later. For example, a hotel may authorize a payment in full prior to a guest's arrival, then move the money when the guest checks out. If the capture_method=manual for the PaymentIntent, the status will move to requires_capture after it has been confirmed.
  • requires_action
    • If the payment requires additional actions, such as authenticating with 3D Secure or physically swiping the card with the terminal during card_present transactions, the PaymentIntent has a status of requires_action.
  • processing
    • Once required actions are handled, the PaymentIntent moves to processing. While for some payment methods (e.g. cards), processing can be quick, other types of payment methods can take up to a few days to process.
  • succeeded
    • A PaymentIntent with a status of succeeded means that the payment flow it is driving is complete.
    • The funds are now in your account and you can confidently fulfill the order. If you need to refund the customer, you can use the Refunds API.
  • canceled
    • You may cancel a PaymentIntent at any point before it processing or succeeded. This invalidates the PaymentIntent for future attempts and cannot be undone. If any funds have been held, cancellation returns those funds.