Pay
Payment API

Processing Payments via API

Learn how to process payments directly through the Transaction API


The Payment API allows you to process payments directly by creating transactions through your backend. This gives you full control over the payment flow and enables you to build custom payment experiences integrated with your application logic. Use the Transaction API when you need programmatic control over payment processing, batch operations, or server-to-server payment flows.

Prerequisites

Before processing payments through the API, it's helpful to learn about the following topics.


When to Use Payment API


Use the Payment API when you need direct, programmatic control over payment processing from your backend. The Transaction API enables server-side payment flows where you manage the entire payment lifecycle through API calls.

By using the Payment API, you handle payment data securely on your backend while Payload manages PCI compliance, card network communication, and settlement processing. You have complete control over payment timing, error handling, and integration with your business logic.

Common use cases

  • Backend Payment Processing: Process payments server-side as part of application workflows
  • Batch Payment Operations: Process multiple payments programmatically
  • Scheduled Payments: Create payments triggered by scheduled jobs or cron tasks
  • Order Fulfillment Integration: Capture authorized payments when orders ship
  • Subscription Billing: Charge customers on recurring schedules using saved payment methods

Processing Card Payments

Process a one-time card payment by creating a transaction with card details.

import payload
pl = payload.Session('secret_key_3bW9...', api_version='v2')
 
# Process a card payment
transaction = pl.Transaction.create(
    type='payment',
    amount=150.00,
    sender={
        'method': {
            'type': 'card',
            'card': {
                'card_number': '4111111111111111',
                'expiry': '12/25',
                'card_code': '123',
            },
            'billing_address': {
                'postal_code': '12345',
            },
        }
    },
    receiver={'account_id': 'acct_receiver123'},
)
 
print(f"Transaction ID: {transaction.id}")
print(f"Status: {transaction.status}")
print(f"Amount: ${transaction.amount}")

This example creates a payment transaction with:

  1. type='payment' specifies this is a payment transaction
  2. amount sets the payment amount in dollars
  3. sender.method.card contains the card details (number, expiry, CVV)
  4. receiver.account_id identifies your account receiving payment

The response includes transaction details with status showing the payment processing state (processing, authorized, processed, declined, or rejected).


Processing Bank Payments

Process bank account payments by providing bank account details.

import payload
 
pl = payload.Session('secret_key_3bW9...', api_version='v2')
 
# Process a bank account payment
transaction = pl.Transaction.create(
    type='payment',
    amount=250.00,
    sender={
        'method': {
            'type': 'bank_account',
            'account_holder': 'John Doe',
            'bank_account': {
                'account_number': '000123456789',
                'routing_number': '110000000',
                'account_type': 'checking',
            },
        }
    },
    receiver={'account_id': 'acct_receiver123'},
)
 
print(f"Transaction ID: {transaction.id}")
print(f"Status: {transaction.status}")
print(f"Amount: ${transaction.amount}")

This example:

  1. Uses sender.method.bank_account instead of card details
  2. Requires account_holder, account_number, and routing_number

Bank account payments follow bank processing timelines and may require additional verification for first-time use.

Canadian Bank Payments

On a Canadian check, the routing number is usually BBBBB-III where I is the institution number and B is the branch or bank transit code. To translate this to an EFT routing number, format it as 0IIIBBBBB. See also Routing numbers (Canada) (opens in a new tab).


Using Saved Payment Methods

Process payments using previously saved payment methods by referencing the payment method ID.

import payload
 
pl = payload.Session("secret_key_3bW9...", api_version="v2")
 
# Process a payment with a saved payment method
transaction = pl.Transaction.create(
    type="payment",
    amount=100.00,
    sender={"method_id": "pm_abc123def456"},
    receiver={"account_id": "acct_receiver123"},
)
 
print(f"Transaction ID: {transaction.id}")
print(f"Status: {transaction.status}")
print(f"Payment Method: {transaction.sender.method_id}")

This example:

  1. References a saved payment method using sender.method_id
  2. No sensitive card or bank details needed in the request
  3. Automatically uses the payment method associated with the customer
  4. Enables faster checkout and recurring payment scenarios

Saved payment methods improve security by avoiding repeated transmission of sensitive data and enable one-click payment experiences.


Authorization and Capture

Use two-step processing to authorize a payment first, then capture it later when ready to settle.

import payload
 
pl = payload.Session("secret_key_3bW9...", api_version="v2")
 
# Step 1: Authorize the payment
transaction = pl.Transaction.create(
    type="payment",
    amount=500.00,
    status={"value": "authorized"},
    sender={
        "method": {
            "type": "card",
            "card": {
                "card_number": "4111111111111111",
                "expiry": "12/25",
                "card_code": "123",
            },
            "billing_address": {"postal_code": "12345"},
        }
    },
    receiver={"account_id": "acct_receiver123"},
)
 
print(f"Authorization ID: {transaction.id}")
print(f"Status: {transaction.status['value']}")
 
# Step 2: Capture the authorized payment
transaction.update(status={"value": "processed"})
 
print(f"Captured Status: {transaction.status['value']}")
print(f"Captured Amount: ${transaction.amount}")

This example demonstrates two-step processing:

  1. Authorization: Set status='authorized' to hold funds without capturing
  2. The authorization validates the card and reserves funds
  3. Capture: Call update() on the transaction with status='processed' to settle
  4. Captured funds are transferred and the transaction completes

Two-step processing is useful when you need to confirm order details, check inventory, or wait for fulfillment before charging the customer.


Enhanced Transaction Data

Include order details, line items, and shipping information with payment transactions.

import payload
 
pl = payload.Session("secret_key_3bW9...", api_version="v2")
 
# Process a payment with enhanced order and shipping details
transaction = pl.Transaction.create(
    type="payment",
    amount=350.00,
    sender={
        "method": {
            "type": "card",
            "card": {
                "card_number": "4111111111111111",
                "expiry": "12/25",
                "card_code": "123",
            },
            "billing_address": {"postal_code": "12345"},
        }
    },
    receiver={"account_id": "acct_receiver123"},
    order_details={
        "cust_ref_number": "INV12345",
        "incl_costs": {"sales_tax": 50.00},
        "line_items": [
            {
                "commodity_code": "3942",
                "description": "Mystery Science Theater 3000",
                "product_code": "MST3000",
                "qty": 1.0,
                "unit_of_measure": "EA",
                "unit_price": 100.00,
                "tax_amount": 25.00,
                "tax_rate": 0.25,
            },
            {
                "commodity_code": "1111",
                "description": "Gogo Gadget Helicopter",
                "product_code": "GGH",
                "qty": 2.0,
                "unit_of_measure": "EA",
                "unit_price": 50.00,
                "tax_amount": 25.00,
                "tax_rate": 0.25,
            },
        ],
    },
    shipping_details={
        "src": {"postal_code": "10001"},
        "dest": {
            "rcpt_first_name": "Testfirst",
            "rcpt_last_name": "Testlast",
            "street_address": "Example St 123",
            "unit_number": "200",
            "city": "Cincinnati",
            "state_province": "OH",
            "postal_code": "45245",
            "country_code": "US",
        },
    },
)
 
print(f"Transaction ID: {transaction.id}")
print(f"Order: {transaction.order_details.order_number}")
print(f"Ship To: {transaction.shipping_details.name}")

This example includes:

  1. order_details with order number and line items
  2. Each line item includes name, SKU, quantity, and unit price
  3. shipping_details with recipient name and address
  4. Enhanced data helps with reporting, reconciliation, and customer support

Including detailed transaction data improves record-keeping, enables better reporting, and provides context for customer service inquiries.


Associating Payments with Customers

Link transactions to customer accounts to maintain payment history and enable saved payment methods.

Reference existing customer account

Process a payment for an existing customer by referencing their account ID.

import payload
 
pl = payload.Session('secret_key_3bW9...', api_version='v2')
 
# Process a payment for an existing customer account
transaction = pl.Transaction.create(
    type='payment',
    amount=200.00,
    sender={
        'method': {
            'type': 'card',
            'card': {'card_number': '4111111111111111', 'expiry': '12/25', 'card_code': '123'},
            'billing_address': {'postal_code': '12345'},
        },
        'account_id': 'acct_customer123',
    },
    receiver={'account_id': 'acct_receiver123'},
)
 
print(f"Transaction ID: {transaction.id}")
print(f"Customer Account: {transaction.sender['account_id']}")
print(f"Amount: ${transaction.amount}")

This example:

  1. Sets sender.account_id to reference an existing customer account
  2. Customer details (name, email, address) are automatically pulled from the account
  3. Provides payment method details (card) for this transaction
  4. Associates the transaction with the customer's payment history

Use this approach when you have already created a customer account using the Accounts API.

Provide customer details inline

Create or update a customer account inline while processing the payment.

import payload
 
pl = payload.Session("secret_key_3bW9...", api_version="v2")
 
# Process a payment with inline customer details
transaction = pl.Transaction.create(
    type="payment",
    amount=200.00,
    sender={
        "method": {
            "type": "card",
            "card": {
                "card_number": "4111111111111111",
                "expiry": "12/25",
                "card_code": "123",
            },
            "billing_address": {"postal_code": "12345"},
        },
        "account": {
            "name": "John Smith",
            "type": "customer",
            "contact_details": {"email": "[email protected]"},
        },
    },
    receiver={"account_id": "acct_receiver123"},
)
 
print(f"Transaction ID: {transaction.id}")
print(f"Customer: {transaction.sender.account_id}")
print(f"Amount: ${transaction.amount}")

This example:

  1. Sets sender.account with inline customer details (name, email)
  2. Creates or updates the customer account as part of the transaction
  3. Provides payment method details (card) for this transaction
  4. Associates the transaction with the customer's payment history

Use this approach when processing a payment for a new customer or when you want to create/update customer details inline.

Linking payments to customers enables customer lifetime value tracking, payment history, and personalized experiences.


Retrieving Transaction Details

Retrieve complete transaction details using the transaction ID.

import payload
pl = payload.Session('secret_key_3bW9...', api_version='v2')
 
# Retrieve a transaction by ID
transaction_id = 'txn_abc123def456'
 
transaction = pl.Transaction.get(transaction_id)
 
print(f"Transaction ID: {transaction.id}")
print(f"Type: {transaction.type}")
print(f"Status: {transaction.status}")
print(f"Amount: ${transaction.amount}")
print(f"Created: {transaction.created_at}")

This allows you to:

  • Check the current transaction status
  • Retrieve payment method details
  • Access order and shipping information
  • View transaction timestamps and processing details
  • Get sender and receiver account information

Listing Transactions

Query transactions by account, type, status, or other filters.

import payload
pl = payload.Session('secret_key_3bW9...', api_version='v2')
 
# List all transactions for an account
account_id = 'acct_receiver123'
 
transactions = pl.Transaction.filter_by(
    receiver={'account_id': account_id},
    type='payment',
    status='processed'
).all()
print(f"Found {len(transactions)} transactions")
for txn in transactions:
    print(f"- {txn.id}: ${txn.amount} ({txn.status})")

This example:

  • Filters transactions by receiver account ID
  • Limits results to payment type transactions
  • Only returns processed transactions
  • Supports pagination for large result sets

Use transaction listing to build reporting dashboards, reconcile payments, and analyze payment activity.

Schema Reference


The following fields are available when creating and configuring payment transactions:

Transaction Configuration

Core fields used when creating payment transactions. For complete API reference, see Transactions API Reference.

type
enum[string]Immutable
The type of transaction being processed. This determines the direction and nature of funds movement, such as payment collection, refund issuance, credit disbursement, or account funding operations.
Values: payment, deposit, withdraw, refund, payout
amount
number (double)
The monetary amount for this transaction in the currency of the processing account. This value is always positive and represents the total value being transferred, collected, or refunded. The amount is rounded to two decimal places for display.
description
string
A human-readable description of what this transaction is for. This text provides context about the purchase, service, or payment purpose and may be displayed to customers on receipts and in transaction histories.
Max length: 128
sender
object
Information about the sender party in this transaction, including the account and payment method from which funds are being sent or debited. For payment transactions, this is the account being charged. For payout transactions, this is the processing account sending funds.
accountAccount
object
The expanded account object for the sender. When included, this provides the full details of the account sending funds in this transaction.
Visibility: explicit
account_id ID of Account
stringImmutable
The unique identifier of the account sending or providing funds for this transaction. This is an optional field that references the account object that owns the sender payment method. (ID prefix: acct)
Pattern: ^acct_[A-Za-z0-9]+$
object
The expanded payment method object used by the sender. When included, this provides the full details of the payment method from which funds are being debited.
method_id ID of PaymentMethod
stringImmutable
The unique identifier of the payment method used by the sender. This references the payment method objectfrom which funds are being pulled or debited for this transaction. If not provided the account default will be used. (ID prefix: pm)
Pattern: ^pm_[A-Za-z0-9]+$
receiver
object
Information about the receiver party in this transaction, including the account and payment method to which funds are being sent or credited. For payment transactions, this is the processing account receiving funds. For payout transactions, this is the account receiving funds.
accountAccount
object
The expanded account object for the receiver. When included, this provides the full details of the account receiving funds in this transaction.
Visibility: explicit
account_id ID of Account
stringImmutable
The unique identifier of the account receiving funds for this transaction. This is an optional field that references the account object that owns the receiver payment method. (ID prefix: acct)
Pattern: ^acct_[A-Za-z0-9]+$
object
The expanded payment method object used by the receiver. When included, this provides the full details of the payment method to which funds are being credited.
method_id ID of PaymentMethod
stringImmutable
The unique identifier of the payment method used by the receiver. This references the payment method object to which funds are being sent or credited for this transaction. If not provided the account default will be used. (ID prefix: pm)
Pattern: ^pm_[A-Za-z0-9]+$
order_details
objectImmutable
Detailed line-item breakdown of the order including individual product amounts, quantities, descriptions, and tax information. This data is used for Level 2 and Level 3 card processing to qualify for lower interchange rates and must match the transaction amount.
cust_ref_number
string
Customer reference number or purchase order (PO) number for this transaction. This is a merchant-assigned identifier used for tracking and reconciliation purposes. Provides additional transaction verification information.
incl_costs
object
Additional costs included in the transaction total. Contains tax and other fees that are part of the total transaction amount. Provides complete cost breakdown.
sales_tax
number (double)
Total amount of sales tax included in the transaction. This is the aggregate tax amount across all line items. Must match the sum of individual line item tax amounts for validation. Used to verify proper tax handling.
line_items
array
Array of individual line items in this order. Each line item represents a distinct product or service being purchased. Provides detailed transaction information. Each line item must include commodity code, description, product code, and unit price. The sum of all line items (including their taxes) must equal the total transaction amount for validation.
shipping_details
objectImmutable
Shipping information for this transaction including the recipient address, shipping method, and costs. This data is used for Level 2 and Level 3 card processing to qualify for lower interchange rates and provide enhanced transaction details.
dest
object
Destination shipping information. Contains complete details about where the goods are being shipped to, including recipient name, company, and full delivery address. Provides enhanced transaction data. Postal code is the only required field.
city
string
City or town of the shipping destination. Part of the complete destination address for enhanced transaction data. Combined with state and postal code to identify the delivery location.
country_code
string
Country code of the shipping destination. Must be either a 2-letter (ISO 3166-1 alpha-2) or 3-letter (ISO 3166-1 alpha-3) country code. For example, "US" or "USA" for United States, "CA" or "CAN" for Canada. Used for international transaction data.
postal_code
string
Postal code (ZIP code) of the shipping destination. Required field for the destination address. Used for enhanced transaction data.
Pattern: ^([A-Z][0-9][A-Z] [0-9][A-Z][0-9]|[0-9]{5}|[0-9]{9})$
rcpt_company
string
Company or organization name of the recipient. Used when shipping to a business location. Helps identify the receiving organization.
rcpt_first_name
string
First name of the recipient receiving the shipment. Part of the complete recipient information for enhanced transaction data. Helps identify the person receiving the goods at the destination address.
rcpt_last_name
string
Last name (surname) of the recipient receiving the shipment. Part of the complete recipient information for enhanced transaction data. Combined with first name to identify the person receiving the goods.
state_province
string
State, province, or region of the shipping destination. For US addresses, use the two-letter state code (e.g., CA, NY). For international addresses, use the appropriate province or region code.
street_address
string
Street address line of the shipping destination. The primary address where goods will be delivered. Part of the complete destination address for enhanced transaction data. Should not include unit numbers (use unit_number field instead).
unit_number
string
Unit, apartment, suite, or other secondary address information for the shipping destination. Use this for apartment numbers, suite numbers, building numbers, etc. Part of the complete destination address.
src
object
Source (origin) shipping information. Contains details about where the goods are being shipped from. Provides enhanced transaction data.
postal_code
string
Postal code (ZIP code) of the origin location where the goods are being shipped from. Provides shipping origin information for enhanced transaction data.
Pattern: ^([A-Z][0-9][A-Z] [0-9][A-Z][0-9]|[0-9]{5}|[0-9]{9})$
source
enum[string]Immutable
The method by which this transaction was initiated or captured. This indicates whether the transaction was submitted via API, manually keyed, swiped through a card reader, processed via EMV chip, captured through NFC/contactless, initiated via digital wallets like Google Pay or Apple Pay, or processed as a check conversion.
Values: api, keyed, swipe, emv, emv_quickchip, nfc, googlepay, applepay, check
status
object
The status information for this transaction, including the current state, a detailed status code, and a human-readable message explaining the result.
code
enum[string]
A machine-readable code detailing the specific reason or result for the transaction status. This provides granular information about success, failure reasons, or other status conditions.
Values: approved, card_expired, duplicate_attempt, exceeded_limit, general_decline, insufficient_bal, invalid_card_code, invalid_card_number, invalid_zip, invalid_address, invalid_account_number, suspicious_activity, too_many_attempts, processing_issue, issue_reading_card, not_supported, general_reject, general_adjustment, payment_stopped
Read-only permissions: "Undocumented"
message
stringRead-only
A human-readable message describing the transaction status and code. This text is suitable for display to users and provides context about the transaction outcome.
value
enum[string]
The current processing status of the transaction, indicating its lifecycle state such as processing, processed, authorized, declined, voided, or rejected.
Values: processing, authorized, processed, declined, rejected, voided, adjusted

Next Steps

Enhance your payment processing implementation


Manage Payment Methods

Create and manage payment methods to enable saved cards and bank accounts for faster checkout.

Handle Refunds and Voids

Process refunds and voids to reverse payments and handle customer returns.

Monitor Payment Events

Subscribe to webhook notifications to track payment status changes and automate workflows.


Related articles