Payment Lifecycles

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

  • completed: The payment has processed and is either in the account's available or reserved balance.
  • 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 youll 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 youll 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 wont 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 youll 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.

POST /payments
Pending
POST /payments/id/capture
Completed

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

POST /payments
Pending
Completed
  • Call POST /payments.
  • WePay sends the payments.in_review notification (must be subscribed) and the payment is in a pending status.
  • The payment passes WePay review and WePay.
  • WePay sends 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,

POST /payments
Pending
payments.manual_review_passed notification
POST /payments/id/capture
Completed
  • Call POST /payments.
  • WePay sends the payments.in_review notification (must be subscribed) and the payment is in a pending status.
  • The payment passes WePay review and WePay.
  • WePay sends the payments.manual_review_passed notification (must be subscribed).
  • Call POST /payments/id/capture.
  • Payment is in a completed status.

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

POST /payments
pending
completed
GET /acounts/id
POST /payments/id/capture
  • Call POST /payments.
  • The payment goes through any lifecycle ending in the completed closing state.
  • Use the owner.path parameter value to call GET /accounts/id.
  • Examine the account's balances.currencies.{currency}.reserve; if there is a reserve balance greater than 0, then reconcile the completed payment against the reserve balance.
  • For more information on reserves, please see our Risk Certification and How Payouts Work guides.

4. An ACH payment is created and processes successfully.

POST /payments
Pending
Completed
  • 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 WePay is required, WePay sends 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.

POST /payments
Pending
Completed
  • 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 WePay:
    • WePay sends the payments.in_review notification (must be subscribed) and the payment is in a pending status.
    • Once the review is completed successfully, WePay sends 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 WePay, then WePay sends 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.

POST /payments
pending
completed
POST /refunds
pending
failed
completed
POST /payments/id/capture
  • 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 will change according to the refund's amount.

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

POST /payments
pending
completed
disputes.created
GET /disputes/id
awaiting decision
resolved
awaiting payee response
pending WePay review
POST /payments/id/capture
  • 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.
  • WePay sends 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.

POST /payments
failed

2. A credit card or ACH payment asynchronously fails WePay's manual review.

POST /payments
pending
payments.in_review
failed
  • Call POST /payments
  • WePay sends the payments.in_review notification (must be subscribed) and the payment is in a pending status.
  • The payment fails manual review, WePay sends the payments.failed notification (must be subscribed), and the payment is in a failed status.
  • In response to the notification, your platform should 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.

POST /payments
pending
failed
payments.failed
  • Call POST /payments.
  • The payment is in a pending status.
  • WePay will send the payments.failed notification (must be subscribed), and the payment is in a failed status.
  • In response to the notification, your platform should make a GET /payments/id call.
  • WePay 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.

POST /payments
pending
failed
payments.failed
  • Call POST /payments.
  • The payment may or may not go into a pending status.
  • WePay will send the payments.failed notification (must be subscribed), and the payment will be in a failed status.
  • In response to the notification, your platform should make a GET /payments/id call.
  • WePay 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.

POST /payments
auto_capture: false
pending
POST /payments/id/cancel
canceled
  • Call POST /payments with the auto_capture parameter set to false.
  • The payment will be in a pending status.
  • Call POST /payments/id/cancel.
  • WePay will send the payments.canceled notification (must be subscribed), and the payment will be in a canceled status.