Best Practices Using Sources

    Best practices to accept a variety of payment methods through a single integration.

    By taking into consideration the flexibility of the Sources API when designing your checkout flow, you can minimize any changes required to support additional payment methods as you add them.

    Typical flow for card payments

    In a typical checkout flow for card payments (excluding 3D Secure), your integration collects the card information and creates a source, then immediately uses it to make a charge request. As there is no additional action for the customer to take, and card payments provide synchronous confirmation, we can immediately confirm if the payment is successful and that the funds are guaranteed—the use of webhooks isn’t necessary.

    The required use of webhooks

    Other payment methods may require your customer to take additional action (e.g., a redirect) before a source becomes chargeable and is ready to be used to make a charge request (e.g., iDEAL). This transition generally happens asynchronously and may even occur after the customer has left your website. For these reasons it is essential that your integration rely on webhooks to determine when a source becomes chargeable in order to create a charge.

    The following webhook events are sent to notify you about changes to the source’s status:

    Event Description
    source.chargeable A Source object becomes chargeable after a customer has authenticated and verified a payment.
    source.failed A Source object failed to become chargeable as your customer declined to authenticate the payment.
    source.canceled A Source object expired and cannot be used to create a charge.

    Similarly, when creating a charge, certain asynchronous payment methods (e.g., SOFORT) may require days for the funds to be confirmed and the charge to succeed, requiring the use of webhooks to know when to confirm and eventually fulfill your orders.

    The following webhooks events are sent to notify you about changes to a charge’s status:

    Event Description
    charge.pending The charge is pending (asynchronous payments only).
    charge.succeeded The charge succeeded and the payment is complete.
    charge.failed The charge has failed and the payment could not be completed.

    Building a flexible integration

    To ensure that your checkout process is flexible and ready to support multiple payment methods, we recommend the following approach:

    Source creation

    When creating Sources, you should record the source ID on your internal order representation so that you can retrieve the order when you receive and process source.chargeable webhooks. You should make sure to index your order objects based on this source attribute for efficient lookup.

    Confirmation page

    After the customer takes the required actions to authorize a payment (as an example, through a redirect) you should present a confirmation page that polls the state of your internal order awaiting final confirmation. Please refer to the customer-facing messaging table below for recommended wordings for this confirmation page.

    Charge creation

    You should rely on the source.chargeable webhook delivery to charge the Source. When receiving the webhook you should retrieve your internal order representation by a look-up based on the received source ID and verify that the order is awaiting a payment.

    When making a charge request, we highly recommend that you use your internal order ID as idempotency key to avoid any possible race condition. Additionally, if the source is reusable and you want to reuse it, make sure to attach it to a Customer before charging it. Refer to the Single-use or reusable and Sources & Customers guides to learn more about how to handle single-use and reusable Sources and how they interact with Customers.

    Similarly to source creation, you should record the charge ID on your internal order representation so that you can retrieve the order when you receive and process charge.succeeded webhooks.

    Order confirmation

    Only confirm your order once you receive the charge.succeeded webhook (either instantly or after a certain amount of time). We highly recommend sending an email to the customer at this stage as the payment confirmation might have taken days for asynchronous payments.

    Cancellations and failures

    You should listen for the source.canceled and source.failed webhooks and make sure to cancel the order associated with the source concerned. If you follow the best practices above, you should never receive a source.canceled webhook for sources that were previously chargeable (as your source.chargeable handler should have created a charge immediately, preventing the source from getting canceled). You will still receive source.canceled webhooks for sources that were never chargeable and remained pending, generally an indication that your customer left your checkout flow early. It is also possible for you to receive a source.failed webhook whenever the Customer refused the payment or a technical failure happened at the payment scheme level.

    You should also listen for the charge.failed webhooks to make sure to cancel the order associated with the received charge.

    For each of these events, we recommend that you contact your customer to let them know that their order failed and maybe invite them to re-engage in your payment flow.

    The following table shows a list of webhook events that your integration should handle along with the action that should be taken on your internal order representation as well as the recommended messaging to display your customers:

    Event Action Customer-facing messaging
    source.chargeable Create a charge Your order was received and is awaiting payment confirmation.
    source.canceled Cancel the order and optionally re-engage the customer in your payment flow Your payment failed and your order couldn’t be processed.
    source.failed Cancel the order and optionally re-engage the customer in your payment flow Your payment failed and your order couldn’t be processed.
    charge.pending Nothing to do Your order was received and is awaiting payment confirmation.
    charge.succeeded Finalize the order and send confirmation over email Your payment is confirmed and your order complete.
    charge.failed Cancel the order and optionally re-engage the customer in your payment flow Your payment failed and your order couldn’t be processed.

    Related resources