Payment Lifecycles

In this article, we'll discuss the different lifecycles a payment can go through.

We'll first talk about a payment from our perspective to help you understand payment flows. Once a payment is created, it will end with one of the below statuses:

  • completed: The payment has processed and can be found either in the available or reserved balance of the account.
  • canceled: The payment has been canceled by the platform and will not show in the account's balance.
  • failed: The payment has not processed due to either an error or a decline.
pending is a transitional payment status indicating that the payment is currently processing. A payment is in pending status after the payments.created Notification is sent, but before any other payment notifications.

Payments will progress through the different statuses according to the Payment Status Flow below:  

Payment Status Flow
Completed
POST /payments
Pending
Canceled
Failed
Refund Status Flow
Completed
POST /refunds
Pending
Failed
Note
Issuing a refund creates a new API object which is separate from the original payment API object. The only change on the original payment API object will be in the amount_refundable parameter.

Payments can go through several statuses before arriving in a closing status. This article discusses those statuses and how payments might reach them.

Payment Flows

It's important to first think about the user experience for payers paying on your Platform. Are they going to input credit card information every time they wish to pay for a good or service? Or will they add a credit card one-time to your platform, which you'll then charge for every payment? Does your platform have a recurring monthly payment option? Use the table below as an approximate guide to figure out which payment flow you'll need.

Payment ExperiencePayment FlowStore Payment MethodCredit CardACH
One-TimeA payer on your platform enters payment information every time they wish to pay for goods or services. All payment information is added, one-time, in the Payments API call, and can be captured immediately, or at a later time. Unlike the other two options, there is no need to create a Payments Method option first. While this means that you won't have to store the users payment method, users will have a less seamless experience.NoNo additional information is needed.No additional information is needed.
Card On FileA payer on your platform enters payment information one time, which you'll represent as a Payment Method in our API. From there, you can use the ID of the Payment Method to charge payments by calling the Payments endpoint.YesUse the card_on_file parameter per card network mandates.While ACH payment methods can be stored on file for future payments, no additional information is needed.
RecurringA payer on your platform enters payment information one time. Unlike Card on File, the user will be billed at a fixed time interval. Like Card on File, you will need to represent payment information using the Payment Method first, then call the Payments API. Read more about how to set up this flow in our Recurring Payments article.YesUse the recurring parameter per card network mandates.While ACH payment methods can be used for recurring payments, no additional information is needed.

When interfacing with the /payments and /payment_methods endpoints, you have an option to collect data using tokenization, instead of capturing raw information like credit card numbers. We always recommend using Tokenization, but will cover both methods. Note, we currently support credit cards and bank accounts as accepted form of payments.

When creating the Card on file and Recurring payment experiences for your platform, subscribe to the payment_method.updated notification topic to be updated when any information on a payment method has changed. This notification also informs your platform of when a credit card has expired, preemptively preventing a failed payment by informing you of an invalid payment_method_id.

Payment Status

As discussed in the Clear Process Payments article, payments can go through various life cycles prior to landing in one of the three closing statuses: completed, failed, or canceled.

Closing Status: completed

Before a given payment lands in the completed closing status, there are 7 possible different payment lifecycles it could go through.

1. A payment is created with the auto_capture parameter set to false and processes successfully.

Merchant/PayerPartnerWePaySubmits Payment InformationPOST /payments{auto_capture: false}{payment_id, payment_method_id, authorization_code}{state:pending, reason_code:processing}Notify Payment is Pending/ProcessingCapture POST /payments/{id}/capturepayments.completed{status:completed}Notify Payment SuccessMerchant/PayerPartnerWePay

2. A payment is created, gets queued for a manual review by us, and passes review successfully.

Merchant/PayerPartnerWePaySubmits Payment InformationPOST /payments{payment_id, payment_method_id, authorization_code}{state:pending, reason_code:processing}Notify Payment is Pending/Processingpayments.in_review{state:pending, reason_code:review}Do Nothing. Maintain Payment in pendingstatus from previous step. Do not sendemails or notificationspayments.completed{status:completed}Notify Payment SuccessMerchant/PayerPartnerWePay
  • Call POST /payments.
  • We send the payments.in_review notification (must be subscribed) and the payment is in a pending status.
  • The payment passes our review.
  • We send the payments.completed notification (must be subscribed) and the payment moves to a completed status.

2.5 A payment is created with the auto_capture parameter set to false, gets queued for manual review, and passes review successfully,

Merchant/PayerPartnerWePaySubmits Payment InformationPOST /payments{auto_capture: false}{payment_id, payment_method_id, authorization_code}{state:pending, reason_code:processing}Notify Payment is Pending/Processingpayments.in_review{state:pending, reason_code:review}Do Nothing. Maintain Payment in pendingstatus from previous step. Do not sendemails or notificationspayments.manual_review_passed{state:pending}Capture POST /payments/{id}/capturepayments.completed{status:completed}Notify Payment SuccessMerchant/PayerPartnerWePay

3. A payment is processed successfully and then gets held in reserves.

Merchant/PayerPartnerWePaySubmits Payment InformationPOST /payments{payment_id, payment_method_id, authorization_code}{state:pending, reason_code:processing}Notify Payment is Pending/Processingpayments.completed{status:completed}Notify Payment SuccessCheck transaction status in Partner Centerstatus should be COMPLETED - RESERVEDopt[Recommended]Merchant/PayerPartnerWePay

4. An ACH payment is created and processes successfully.

Merchant/PayerPartnerWePaySubmits Payment InformationPOST /payments withpayment_bank_us payment method or token{payment_id, payment_method_id, authorization_code}{state:pending, reason_code:processing}Notify Payment is Pending/Processingpayments.completed{status:completed}Notify Payment SuccessMerchant/PayerPartnerWePay
  • Call POST /payments with a payment_bank_us payment method or token.
  • The ACH payment will be in a standard 2 business day hold and have a pending status.
  • Assuming that no manual review by us is required, we send the payments.completed notification (must be subscribed) and the ACH payment will move into a completed status.

5. A payment is created with the auto_capture parameter set to true and processes successfully.

Queue for Manual ReviewNo Queue for Manual Review
Merchant/PayerPartnerWePaySubmits Payment InformationPOST /payments{auto_capture: true}{payment_id, payment_method_id, authorization_code}{state:pending, reason_code:processing}Notify Payment is Pending/Processingpayments.in_review{state:pending, reason_code:review}Do Nothing. Maintain Payment in pendingstatus from previous step. Do not sendemails or notificationspayments.manual_review_passed{state:pending}payments.completed{status:completed}Notify Payment SuccessMerchant/PayerPartnerWePay
Merchant/PayerPartnerWePaySubmits Payment InformationPOST /payments{auto_capture: true}payments.completed{status:completed}Notify Payment SuccessMerchant/PayerPartnerWePay
  • Call POST /payments (the auto_capture parameter can be set to true or omitted from the call).
  • If the payment queues for a manual review from us:
    • We send the payments.in_review notification (must be subscribed) and the payment is in a pending status.
    • Once the review is completed successfully, we send the payments.manual_review_passed notification (must be subscribed) and the payment moves to a completed status.
  • If the payment did not queue for a manual review from us, then we send the payments.completed notification (must be subscribed) and the payment moves to a completed status right away.

6. A payment is created, processes successfully, and is then refunded.

Merchant/PayerPartnerWePaySubmits Payment InformationPOST /payments{payment_id, payment_method_id, authorization_code}{state:pending, reason_code:processing}Notify Payment is Pending/Processingpayments.completed{status:completed}Notify Payment SuccessPOST /refundsamount_refundable (found on the Payment resource)changes according to refund amountMerchant/PayerPartnerWePay
  • Consider any of the above life cycles with a payment in a completed status.
  • A refund needs to be issued, so your platform calls POST /refunds.
  • The payment API object will remain in a completed status, but the amount_refundable (found on the Payment object) will change according to the refund's amount.

7. A payment is created, processes successfully, and is then disputed.

Merchant/PayerPartnerWePaySubmits Payment InformationAuth POST /payments{payment_id, payment_method_id, authorization_code}{state:pending, reason_code:processing}Notify Payment is Pending/Processingpayments.completed{status:completed}Notify Payment Successdisputes.createdGET /disputes/{id}Payment remains in completed statusOutcome of dispute reflected in dispute's statusMerchant/PayerPartnerWePay
  • Consider any of the above life cycles with a payment in a completed status.
  • The card issuer starts the chargeback process, and a dispute is created.
  • We send the disputes.created notification (must be subscribed).
  • Call GET /disputes/id using to the ID provided in the notification.
  • The payment will remain in a completed status, and the outcome of the dispute will be reflected in the dispute's status.

Closing Status: failed

Before a given payment lands in the failed closing status, there are few possible different payment lifecycles it could go through.

1. A payment synchronously fails.

Merchant/PayerPartnerWePaySubmits Payment InformationPOST /paymentsOne of the following API error codes:MERCHANT_ACCOUNT_CANNOT_ACCEPT_PAYMENTSTRANSACTION_DECLINEDUNSUPPORTED_CURRENCYMerchant/PayerPartnerWePay

2. A credit card or ACH payment asynchronously fails our manual review.

Merchant/PayerPartnerWePaySubmits Payment InformationPOST /payments{payment_id, payment_method_id, authorization_code}{state:pending, reason_code:processing}Notify Payment is Pending/Processingpayments.in_review{state:pending, reason_code:review}Do Nothing. Maintain Payment in pendingstatus from previous step. Do not sendemails or notificationspayments.failed{state: failed, reason_code: review}Notify Payment FailedGET /payments/{id}payload.failure_reason returnedopt[Optional]Merchant/PayerPartnerWePay
  • Call POST /payments
  • We send the payments.in_review notification (must be subscribed) and the payment is in a pending status.
  • The payment fails manual review, we send the payments.failed notification (must be subscribed), and the payment is in a failed status.
  • In response to the notification, we recommend that your platform either examine the payload.failure_reason structure, or make a GET /payments/id call. The following will return in the failure_reason parameter:
Copy
Copied
{
  "failure_reason": {
    "reason_code": "REVIEW",
    "reason_message": "Failed to capture the payment.",
    "details": {
      "detail_code": "risk_review",
      "detail_message": "The payment could not be captured as it failed risk review"
     }
   }
}

3. An ACH payment asynchronously fails.

Merchant/PayerPartnerWePaySubmits Payment InformationPOST /payments{payment_id, payment_method_id, authorization_code}{state:pending, reason_code:processing}Notify Payment is Pending/Processingpayments.failed{state: failed, reason_code: review}Notify Payment FailedGET /payments/{id}One of the following ACH-specific failure_reason.reason_code:ECHECK_FRAUDBANK_NOT_CONFIRMEDBANK_SYSTEM_ERRORopt[Optional]Merchant/PayerPartnerWePay
  • Call POST /payments.
  • The payment is in a pending status.
  • We will send the payments.failed notification (must be subscribed), and the payment is in a failed status.
  • In response to the notification, we recommend that your platform make a GET /payments/id call.
    • We will return one of the following ACH-specific failure_reason.reason_code values:
      • ECHECK_FRAUD
      • BANK_NOT_CONFIRMED
      • BANK_SYSTEM_ERROR
    • Examine the ACH failure details for guidance on next steps.
Here's an example of ACH-specific failure_reason JSON:
Copy
Copied
{
  "failure_reason": {
    "reason_code": "BANK_NOT_CONFIRMED",
    "reason_message": "Failed to capture the payment due to incorrect information",
    "details": {
      "detail_code": "R04",
      "detail_message": "Invalid account number"
    }
  }
}

4. A credit card payment asynchronously fails.

Merchant/PayerPartnerWePaySubmits Payment InformationPOST /payments{payment_id, payment_method_id, authorization_code}{state:pending, reason_code:processing}Notify Payment is Pending/Processingpayments.failed{state: failed, reason_code: review}Notify Payment FailedGET /payments/{id}payload.failure_reason returnedopt[Optional]Merchant/PayerPartnerWePay
  • Call POST /payments.
  • The payment may or may not go into a pending status.
  • We will send the payments.failed notification (must be subscribed), and the payment will be in a failed status.
  • In response to the notification, we recommend that your platform make a GET /payments/id call.
    • We will return the following credit-card-specific failure_reason JSON:
Copy
Copied
{
  "failure_reason": {
    "reason_code": "NOT_CAPTURED",
    "reason_message": "Failed to capture the payment",
    "details": {
      "detail_code": "XX",
      "detail_message": "XX"
    }
  }
}
  • For more information on credit-card-specific details values, see their possible values.

Closing Status: canceled

Before a given payment lands in the canceled closing status, there are a few possible different payment lifecycles it could go through.

1. A payment is created with the auto_capture parameter set to false and a POST /payments/{id}/cancel call is made.

Merchant/PayerPartnerWePaySubmits Payment InformationPOST /payments{auto_capture: false}{payment_id, payment_method_id, authorization_code}{state:pending, reason_code:processing}Notify Payment is Pending/ProcessingPOST /payments/{id}/cancelpayments.canceled{status: canceled}Notify Payment CanceledMerchant/PayerPartnerWePay
  • Call POST /payments with the auto_capture parameter set to false.
  • The payment will be in a pending status.
  • Call POST /payments/{id}/cancel.
  • We will send the payments.canceled notification (must be subscribed), and the payment will be in a canceled status.