Skip to main content

Using Payments API

Implementing the Payment Intent Flow with Accrue Pay

Introduction

This guide provides a comprehensive overview of the Payment Intent flow within Accrue Pay's Merchant API. Payment Intents represent a customer’s intent to make a payment and are used to track and manage a payment’s lifecycle from creation to settlement.

What is a Payment Intent?

A Payment Intent is a key object that:

  • Captures the customer’s selected payment method (Accrue Wallet or Bank Account)
  • Represents their choices at checkout
  • Manages payment authorization, capture, and settlement
  • Tracks the state of a payment across its entire lifecycle

End-to-End Integration Flow

The following diagram outlines the full integration journey across Customer, Merchant Frontend, Merchant Backend, and Accrue Pay:

End-to-End Integration Diagram

Flow Overview

  1. Customer Interaction (Merchant Frontend)

    • Customer selects Accrue Pay at checkout
    • Completes checkout flow with either Wallet or Bank Account
    • Completes any necessary authentication
    • A Payment Intent is created via the frontend SDK
  2. Frontend to Backend Handoff

    • The frontend sends the Payment Intent ID to your backend
    • The backend prepares to authorize the intent
  3. Backend Processing

    • Authorizes the Payment Intent, converting it into a Payment
    • Captures the authorized payment
    • Confirms success and updates the order status
  4. Finalization

    • Merchant fulfills the order
    • Accrue Pay settles funds based on the agreed schedule

Detailed Payment Intent Flow

1. Creating a Payment Intent

A Payment Intent is initiated when the customer selects Accrue Pay and a payment method. The frontend SDK handles:

  • Presenting payment method options
  • Authenticating the user
  • Initiating the Payment Intent object with the selected method

2. Authorizing a Payment Intent

Once the Payment Intent is created, your backend must authorize it. Authorization reserves the funds and converts the intent into a Payment.

Authorize Payment Intent Diagram

API Endpoint: POST /api/v1/payment-intents/:paymentIntentId/authorize

Headers: Client-ID, Authorization: Bearer <client-secret>, Content-Type: application/vnd.api+json

Request:

{
"data": {
"type": "AuthorizePaymentIntent",
"attributes": {
"amount": 10000,
"reference": "order-12345",
"channel": "ORG-1",
"risk": {
"deviceSessionId": "device-session-abc123"
}
}
}
}

reference, channel, and risk are optional. When card processing is enabled for your integration, Accrue provides the optional meta.processor request shape separately during onboarding — do not infer it from public docs.

Response:

The response returns the Payment Intent in data and the created Payment in included. When a wallet is attached, balance information may appear on the payment intent attributes.

{
"data": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"type": "PaymentIntent",
"attributes": {
"amount": 10000,
"status": "PromotedToPayment",
"reference": "order-12345",
"userId": "123e4567-e89b-12d3-a456-426614174000",
"walletId": "223e4567-e89b-12d3-a456-426614174001"
},
"relationships": {
"payments": {
"data": [
{
"id": "323e4567-e89b-12d3-a456-426614174002",
"type": "Payment"
}
]
}
}
},
"included": [
{
"id": "323e4567-e89b-12d3-a456-426614174002",
"type": "Payment",
"attributes": {
"amount": 10000,
"status": "Created",
"reference": "order-12345",
"expiresAt": "2025-05-19T14:22:33.000Z"
}
}
]
}

Behavior notes:

  • If the payment intent was already authorized, the existing active payment is returned without re-authorizing.
  • When a card processor is configured, processor authorization runs inline. A declined processor authorization returns 402 and marks the payment Failed.
  • Card-processor responses may attach opaque processor data on included[].meta.processor.

3a. Capturing a Payment (Bank Rails)

Authorized payments must be captured to initiate fund transfers. Capture can be automatic or manual, depending on your configuration.

Capture Payment Diagram

API Endpoint: POST /api/v1/payments/:paymentId/capture

Request:

{
"data": {
"type": "CapturePayment",
"attributes": {
"amount": 10000
}
}
}

Response:

{
"data": {
"id": "323e4567-e89b-12d3-a456-426614174002",
"type": "Payment",
"attributes": {
"amount": 10000,
"status": "Processing",
"reference": "order-12345"
},
"relationships": {
"paymentIntent": {
"data": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"type": "PaymentIntent"
}
}
}
},
"included": [
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"type": "PaymentIntent",
"attributes": {
"amount": 10000,
"status": "PromotedToPayment"
}
}
]
}

3b. Capturing a Payment (Card Rails - Using Virtual Debit card)

When using the card rails integration option, Accrue Pay provides a virtual debit card that you can process through your existing payment gateway.

After authorizing the Payment Intent, follow these steps to capture the payment using the virtual debit card:

Step 1: Retrieve the virtual debit card details using the secure API

Get Virtual Debit Card

API Endpoint: GET https://secure-api.accruesavings.com/api/v1/payments/:paymentId/card

Headers:

Client-ID: your_client_id
Authorization: Bearer your_client_secret
Content-Type: application/vnd.api+json

Response:

{
"data": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"type": "VirtualDebitCard",
"attributes": {
"number": "5555555555554444",
"expirationMonth": "6",
"expirationYear": "2028",
"cvc": "123",
"billingAddress": {
"street": "123 Main St.",
"street2": "Apt. 1",
"city": "San Francisco",
"state": "CA",
"postalCode": "94107",
"country": "US"
}
},
}
}

Step 2: Process the virtual debit card through your payment gateway

Use your existing payment gateway to process the virtual debit card details:

  1. Submit the card details (number, expirationMonth, expirationYear, cvc) to your payment gateway
  2. Use the same amount that was authorized in the Payment Intent
  3. Store both the Accrue Pay payment ID and your gateway's transaction ID for reconciliation

Example integration with a payment gateway:

// Example code - implement according to your payment gateway's API
const processMastercard = async (cardDetails, amount) => {
const response = await paymentGateway.processCard({
card_number: cardDetails.attributes.number,
expiry_month: cardDetails.attributes.expirationMonth,
expiry_year: cardDetails.attributes.expirationYear,
cvv: cardDetails.attributes.cvc,
billing_address: {
street: cardDetails.attributes.billingAddress.street,
street2: cardDetails.attributes.billingAddress.street2,
city: cardDetails.attributes.billingAddress.city,
state: cardDetails.attributes.billingAddress.state,
postal_code: cardDetails.attributes.billingAddress.postalCode,
country: cardDetails.attributes.billingAddress.country
},
amount: amount,
currency: 'USD',
description: 'Order #12345 (Accrue Pay Virtual Card)'
});

return response.transaction_id;
};

Important Notes on Card Rail Integration:

  • Never store the full card details on your servers; use them only for the immediate payment processing
  • Ensure your system is PCI compliant if handling card data
  • The virtual debit card is a single-use card tied to the specific authorized amount
  • For future payments from the same customer, you'll need to generate a new virtual card
  • If needed, you can cancel the authorization by calling the /payments/:paymentId/cancel endpoint

Payment Lifecycle

Payment Intent statuses:

StatusDescription
PromotableReady to authorize
PromotedToPaymentAuthorized; an active payment exists
InvalidCannot be used (validation or KYC issue)
ExpiredPast expiresAt
CanceledCanceled before completion

Payment statuses (after authorize):

StatusDescription
CreatedAuthorized; awaiting capture or processor completion
ProcessingCapture or settlement in progress
SentCompleted successfully
FailedAuthorization or processing failed
CanceledCanceled before completion
ReturnedReturned after completion

See the API reference for the full schema.


Error Handling

Accrue Pay returns standard HTTP status codes with JSON:API error bodies.

Status CodeMeaning
400Invalid request or validation error
401Authentication failed
402Payment authorization or capture failed
403Permission denied
404Resource not found
500Internal server error

Example error response (authorize failure):

{
"id": "error-uuid",
"status": 402,
"code": "Failed",
"title": "PaymentAuthorizationFailedException",
"detail": "Authorization failed for the desired amount",
"meta": {
"environment": "sandbox",
"timestamp": "2025-05-12T14:22:33.000Z",
"path": "/api/v1/payment-intents/497f6eca-6276-4993-bfeb-53cbbbba6f08/authorize"
}
}

Best Practices

1. Lifecycle Management

  • Persist Payment Intent ID with your order data
  • Implement retry logic for recoverable errors
  • Use webhooks to track payment status updates asynchronously

2. Security Guidelines

  • All sensitive operations (authorize, capture) must be backend-only
  • Never expose API credentials in frontend code
  • Implement idempotency keys to prevent duplicate operations

3. Testing and Go-Live Readiness

  • Use the Sandbox environment for full integration testing
  • Simulate both successful and failed scenarios
  • Validate end-to-end flow including fund settlement before production launch

The Payment Intent architecture enables a flexible and secure integration path for handling payments with Accrue Pay. Following this implementation guide will help ensure a reliable and compliant checkout experience. See also the Merchant API Integration guide for backend authorization and capture details.

Ready to implement Accrue Pay in your application?

Contact us at info@byaccrue.com to get started