Skip to content

Make Your First Payment

This guide walks you through creating and executing your first payment using TreasuryPath. You'll learn how to generate a quote, create a payment using that quote, and track the payment status.

What You'll Learn

  • How to get payment profile IDs from your bank accounts
  • How to create a payment quote
  • How to create a payment using the quote
  • How to track payment status via webhooks
  • Understanding payment lifecycle and statuses

Prerequisites

Before making payments:

Understanding Payments

Payments are financial transfers between two payment profiles - typically from your funding account (source) to a recipient's bank account (destination).

Key Concepts

  • Payment Quotes: Provide pricing, fees, and timing information before creating a payment
  • Quote Validity: Quotes expire 15 minutes after creation
  • Payment Profiles: Each bank account has payment profiles that define usage type (debit, credit, balance)
  • Idempotency: Prevents duplicate payments using unique idempotency keys
  • Payment Reasons: Required codes that categorize the payment purpose for compliance

How It Works

YourApplicationTreasuryPathAPI 1. List bank accounts(GET /bank_accounts) Return accounts withpayment profiles 2. Create quote(POST /quotes) Quote created(valid 15 minutes) 3. Create payment(POST /payments) Payment created(status: pending) 4. Webhook(PaymentEvents::CompletedEvent)
YourApplicationTreasuryPathAPI 1. List bank accounts(GET /bank_accounts) Return accounts withpayment profiles 2. Create quote(POST /quotes) Quote created(valid 15 minutes) 3. Create payment(POST /payments) Payment created(status: pending) 4. Webhook(PaymentEvents::CompletedEvent)

Step 1: Get Payment Profile IDs

Before creating a payment, retrieve the payment profile IDs from your bank accounts.

List Bank Accounts

curl -X GET "https://api.treasurypath.com/api/v1/companies/{company_id}/bank_accounts" \
  -H "Authorization: Bearer {your_jwt_token}"

Replace: - {company_id} - Your company ID - {your_jwt_token} - Your JWT authentication token

Example Response

{
  "data": [
    {
      "id": "Z2lkOi8vd2FsbGV0LWFwcC9CYW5rQWNjb3VudC82NQ",
      "currency": "USD",
      "owner_type": "Entity",
      "payment_profiles": [
        {
          "id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50UHJvZmlsZS81",
          "status": "active",
          "currency": "USD",
          "payment_method": "ach",
          "usage_type": "debit"
        }
      ]
    },
    {
      "id": "Z2lkOi8vd2FsbGV0LWFwcC9CYW5rQWNjb3VudC82Ng",
      "currency": "USD",
      "owner_type": "Counterparty",
      "payment_profiles": [
        {
          "id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50UHJvZmlsZS83",
          "status": "active",
          "currency": "USD",
          "payment_method": "ach",
          "usage_type": "credit"
        }
      ]
    }
  ]
}

Identify Payment Profiles

From the response, identify:

  • Source Profile (from_profile_id): Payment profile with usage_type: "debit" from your funding account
  • Destination Profile (to_profile_id): Payment profile with usage_type: "credit" from the recipient's account

Active Profiles Required

Both payment profiles must have status: "active" to create a quote and payment.

Save Profile IDs

Copy and save: - The id from the debit payment profile for from_profile_id - The id from the credit payment profile for to_profile_id

Step 2: Create a Payment Quote

Generate a quote to get pricing, fees, exchange rates, and expected completion date for your payment.

curl -X POST "https://api.treasurypath.com/api/v1/companies/{company_id}/quotes" \
  -H "Authorization: Bearer {your_jwt_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "quote": {
      "from_profile_id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50UHJvZmlsZS81",
      "to_profile_id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50UHJvZmlsZS83",
      "instructed_amount": {
        "amount": 1000.00,
        "currency": "USD"
      }
    }
  }'

Replace: - {company_id} - Your company ID - {your_jwt_token} - Your JWT authentication token - from_profile_id - Payment profile ID with usage_type: "debit" from Step 1 - to_profile_id - Payment profile ID with usage_type: "credit" from Step 1 - amount - Payment amount - currency - Payment currency (e.g., "USD", "EUR", "GBP")

Request Parameters

Parameter Type Required Description
from_profile_id string Yes Source payment profile ID (usage_type: "debit")
to_profile_id string Yes Destination payment profile ID (usage_type: "credit")
instructed_amount.amount number Yes Payment amount
instructed_amount.currency string Yes ISO 4217 currency code

Success Response

{
  "data": {
    "id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50UXVvdGUvMQ",
    "created_at": "2025-01-17T10:30:00.000Z",
    "updated_at": "2025-01-17T10:30:00.000Z",
    "instructed_amount": "1000.0",
    "instructed_amount_currency": "USD",
    "source_amount": "1000.0",
    "source_amount_currency": "USD",
    "target_amount": "1000.0",
    "target_amount_currency": "USD",
    "exchange_rate": "1.0",
    "expires_at": "2025-01-17T10:45:00.000Z",
    "fee": "0.0",
    "fee_currency": "USD",
    "expected_completion_date": "2025-01-18",
    "from_profile": {
      "id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50UHJvZmlsZS81",
      "status": "active",
      "currency": "USD",
      "payment_method": "ach",
      "usage_type": "debit"
    },
    "to_profile": {
      "id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50UHJvZmlsZS83",
      "status": "active",
      "currency": "USD",
      "payment_method": "ach",
      "usage_type": "credit"
    }
  }
}

Important Quote Fields

  • id: Quote identifier - save this for creating the payment
  • expires_at: Quote expiration time (15 minutes from creation)
  • fee: Fee amount that will be charged
  • source_amount: Total amount debited from source (includes fees)
  • target_amount: Amount credited to destination
  • exchange_rate: Exchange rate (1.0 for same-currency transfers)
  • expected_completion_date: When the payment is expected to complete

Quote Expiration

Quotes expire 15 minutes after creation. The expires_at field shows the exact expiration time. After expiration, generate a new quote to create a payment.

Save the Quote ID

Copy and save the id field from the data object - you'll need this payment_quote_id for creating the payment in the next step.

Step 3: Create the Payment

Using the quote ID from Step 2, create a payment instruction to execute the transfer.

curl -X POST "https://api.treasurypath.com/api/v1/companies/{company_id}/payments" \
  -H "Authorization: Bearer {your_jwt_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_instruction": {
      "payment_quote_id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50UXVvdGUvMQ",
      "reason": "business_expenses",
      "idempotency_key": "unique-payment-12345-abcdef",
      "credit_note": "Invoice #1234 payment",
      "debit_note": "Payment for services"
    }
  }'

Replace: - {company_id} - Your company ID - {your_jwt_token} - Your JWT authentication token - payment_quote_id - Quote ID from Step 2 - reason - Payment reason code (see Payment Reason Codes) - idempotency_key - Unique identifier to prevent duplicate payments - credit_note - Optional note visible to the recipient - debit_note - Optional note for internal reference

Request Parameters

Parameter Type Required Description
payment_quote_id string Yes Quote ID from Step 2
reason string Yes Payment reason code (e.g., "business_expenses")
idempotency_key string Yes Unique key to prevent duplicate payments
credit_note string No Note visible to the recipient
debit_note string No Internal note for the sender

Success Response

{
  "data": {
    "id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50SW5zdHJ1Y3Rpb24vMQ",
    "created_at": "2025-01-17T10:30:00.286Z",
    "updated_at": "2025-01-17T10:30:00.286Z",
    "instructed_amount": "1000.0",
    "instructed_amount_currency": "USD",
    "quote_id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50UXVvdGUvMQ",
    "reason": "business_expenses",
    "status": "pending",
    "idempotency_key": "unique-payment-12345-abcdef",
    "from_profile": {
      "id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50UHJvZmlsZS81",
      "status": "active",
      "currency": "USD",
      "payment_method": "ach",
      "usage_type": "debit"
    },
    "to_profile": {
      "id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50UHJvZmlsZS83",
      "status": "active",
      "currency": "USD",
      "payment_method": "ach",
      "usage_type": "credit"
    }
  }
}

Payment Created

The payment has been successfully created with status: "pending". Save the payment id to track its status.

Understanding Payment Reason Codes

Payment reason codes are required for regulatory compliance. Common codes include:

Code Description Use Case
business_expenses General business expenses Operational costs, supplies, equipment
professional_business_services Professional services Legal, accounting, consulting fees
goods_purchased Goods purchased Inventory, raw materials, products
bill_payment Bill payment Utilities, rent, subscriptions
wages_salary Wages or salary Employee compensation, payroll
transfer_to_own_account Internal transfer Moving funds between your accounts

For the complete list, see Payment Reason Codes.

Understanding Idempotency Keys

Idempotency keys prevent accidental duplicate payments:

  • Unique per payment: Each distinct payment requires a unique key
  • Format: Use UUIDs or unique identifiers (e.g., "order-12345-20250117-001")
  • Behavior: Submitting the same key multiple times returns the existing payment
  • Scope: Keys are scoped to your company

Generating Idempotency Keys

Use a UUID library or combine unique identifiers like order ID + timestamp. Examples: - "uuid-a7b3c1d9-e2f4-4a5b-8c9d-0e1f2a3b4c5d" - "invoice-INV-2025-001-20250117" - "payroll-2025-01-15-employee-12345"

Step 4: Monitor Payment Status

Track the payment status through webhooks or API polling.

Payment Lifecycle

Payments progress through these statuses:

pendingprocessingcompletedfailed Payment submittedto network Paymentsuccessfully processed Paymentfailed
pendingprocessingcompletedfailed Payment submittedto network Paymentsuccessfully processed Paymentfailed
Status Description
pending Payment created but not yet submitted to the payment network
processing Payment is being processed by the payment network
completed Payment successfully completed (terminal status)
failed Payment failed and will not be processed (terminal status)

Set up webhooks to receive real-time payment status updates.

Payment Completed Event

Event Type: PaymentEvents::CompletedEvent

Triggered when a payment successfully completes.

{
  "event": "PaymentEvents::CompletedEvent",
  "timestamp": "2025-01-17T14:30:00.000Z",
  "company_id": "Z2lkOi8vYXBwL0NvbXBhbnkvMTIz",
  "resource_id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50SW5zdHJ1Y3Rpb24vNDU2",
  "actor_id": null
}

Payment Failed Event

Event Type: PaymentEvents::FailedEvent

Triggered when a payment fails to process.

{
  "event": "PaymentEvents::FailedEvent",
  "timestamp": "2025-01-17T14:30:00.000Z",
  "company_id": "Z2lkOi8vYXBwL0NvbXBhbnkvMTIz",
  "resource_id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50SW5zdHJ1Y3Rpb24vNDU2",
  "actor_id": null
}

Setting Up Webhooks

Configure webhook endpoints to receive these notifications. See the Webhooks Guide for setup instructions.

Alternative: Check Payment Status via API

If webhooks aren't configured, poll the payment details endpoint:

curl -X GET "https://api.treasurypath.com/api/v1/companies/{company_id}/payments/{payment_id}" \
  -H "Authorization: Bearer {your_jwt_token}"

Common Errors

Quote Expired

{
  "errors": [
    {
      "field": "payment_quote_id",
      "message": "Quote has expired"
    }
  ]
}

Solution: Quotes expire 15 minutes after creation. Generate a new quote and create the payment using the new quote ID.

Invalid Payment Profile

{
  "errors": [
    {
      "field": "from_profile_id",
      "message": "Payment profile is not in active status"
    }
  ]
}

Solution: Ensure both payment profiles have status: "active". Inactive, draft, or failed profiles cannot be used for quotes or payments.

Missing Idempotency Key

{
  "errors": [
    {
      "field": "idempotency_key",
      "message": "Idempotency key is required"
    }
  ]
}

Solution: Include a unique idempotency_key in your payment request.

Invalid Reason Code

{
  "errors": [
    {
      "field": "reason",
      "message": "Invalid payment reason code"
    }
  ]
}

Solution: Use a valid payment reason code from the Payment Reason Codes reference.

Insufficient Funds

If a payment fails due to insufficient funds, you'll receive a PaymentEvents::FailedEvent webhook. Fetch the payment details to see the specific failure reason.

Solution: Ensure the funding account has sufficient balance before creating payments.

Best Practices

Quote Management

  • ✅ Generate quotes immediately before creating payments
  • ✅ Check the expires_at field and act within 15 minutes
  • ✅ Generate new quotes if exchange rates or fees need updating
  • ✅ Save quote IDs for payment creation and record-keeping

Payment Creation

  • ✅ Always use unique idempotency keys for each distinct payment
  • ✅ Choose accurate payment reason codes for compliance
  • ✅ Include descriptive notes (credit_note, debit_note) for clarity
  • ✅ Verify payment profile IDs before creating quotes

Status Monitoring

  • ✅ Use webhooks for real-time status updates (recommended)
  • ✅ Store payment IDs for tracking and reconciliation
  • ✅ Handle both completed and failed payment events
  • ✅ Monitor failed payments and notify relevant parties

Security and Compliance

  • ✅ Never reuse idempotency keys across different payments
  • ✅ Verify webhook signatures to ensure authenticity
  • ✅ Use HTTPS for all API communications
  • ✅ Follow regulatory requirements for payment categorization

Error Handling

  • ✅ Implement retry logic for expired quotes
  • ✅ Handle payment failures gracefully
  • ✅ Provide clear error messages to users
  • ✅ Log all payment attempts for audit trails

What's Next?

Once you've made your first payment, you can:

  1. Set Up Webhooks - Configure real-time payment notifications
  2. List Payments - View all payments for your company
  3. Cross-Currency Payments - Create payments between different currencies
  4. Manage Multiple Payment Methods - Use different payment methods (ACH, Wire, SWIFT)

API Reference

For complete API documentation, see:

Need Help?

  • Check the FAQ for common questions
  • Contact support at support@treasurypath.com