Skip to main content
A payment is one charge of a payment method you already created: a pay_test_… / pay_live_… object your server creates with a secret key. A card is captured in the same answer; a bank debit is processing until it settles, when the processor sends it to the bank in its next batch. The charge runs through the same engine as the rest of Payra, so it shows up in the dashboard, reconciles and refunds like any other payment.
1

Charge the payment method

Response
amount is in the smallest unit of the currency, so 12550 is $125.50, and it is charged exactly: the API adds no fee or surcharge. amount_refunded is how much of it has since gone back through refunds, wherever they were made. currency is USD or CAD; charge CAD only on a workspace Payra has set up to take Canadian dollars. description and reference are optional, the second being your own order or invoice number: it is stored as the payment’s order number and shown in the dashboard, and it does not apply the payment to a Payra invoice. When the method is saved on a customer and reference matches one of that customer’s prepayment orders (orders synced from your ERP through Payra Connect), the charge counts against that order: amount may not exceed what is still due on it, other pending charges included (400 parameter_invalid on amount), and a succeeded charge reduces what is due. customer, if you send it, must be the customer the method is saved on.
2

Read it back while it settles

A declined payment stays readable at the same id: the create answered 402, and this is where you see why.
An Idempotency-Key is required. The same key with the same body answers the same payment, including after a crash on our side, because the payment itself remembers the key. The same key with a different body is 400 idempotency_key_reused; after 24 hours only payment_method, amount and currency are compared. Charging a saved payment method emails the customer Payra’s payment receipt once the charge succeeds (for a bank debit, when the processor accepts the debit, before it settles), when the customer has an email address whose email notifications are on, the workspace’s Email payment receipts to customers setting is on, and its notifications are not paused. A one-time method has no customer, so its payment gets no receipt. A one-time payment method is spent by its first charge, approved or declined, and reads consumed afterwards. Only a request refused before it reaches the processor (a 400 on amount, currency or customer, payment_provider_not_configured, or a reused key) leaves it active. A saved one can be charged again.

Bank debits

A bank account is charged for what its holder authorized. A one-time account takes exactly the amount and currency its session named, else 400 parameter_invalid on amount; a saved one takes the amount you send. currency is USD. The answer is a processing payment with payment_method_type: "us_bank_account" and a us_bank_account block (last4, account_type, account_holder_type), card being null:
It becomes succeeded when it settles, once the processor’s next batch sends it to the bank, and succeeded_at is set then; the bank can instead refuse the debit, which turns it returned with failure.code: "ach_returned", or the processor can reject it outright, which turns it failed. Listen for payment.succeeded, payment.returned and payment.failed rather than polling, and do not ship on processing. Every debit carries the authorization evidence Payra recorded when the holder accepted it, so a dispute can be answered from Payra’s records.

Status

status is Payra’s own lifecycle. It is never a string from the processor.

Why a payment failed

failure is set when status is failed or returned, and null otherwise. It carries a code from a fixed vocabulary and a message written by Payra. The processor’s own wording is never relayed, so you can show or log message safely and branch on code.

Declines

A refusal is an answer, not an outage: the create responds 402 card_declined and leaves the payment behind for you to read.
code is card_declined for every refusal, so decline_code is what you branch on. It uses the same vocabulary as failure.code, which means it can be processing_error: that one is not the issuer refusing the card, and it is worth retrying with a new Idempotency-Key (the same key replays this 402). A saved method can simply be charged again; a one-time method was spent by the attempt, so collect the card again with a new session. A charge the processor refuses, or that Payra could not send at all (the workspace has no processor account for that currency, say), answers this same 402, never a 500: the failed payment exists, reads back and lists. When Payra cannot tell whether the processor received the charge (the request timed out, or the connection failed), the create answers 201 with status: "processing" instead, and a later webhook says how it ended.

Listing payments

GET /payments answers the payments your keys have made, newest first, a page at a time. It takes limit and starting_after, and works the same as every other list; see pagination for walking the pages.
Response (abbreviated)
The list only ever holds your own workspace’s payments, in the environment of the key you sent. The list takes no filters; when you already know an id, read it with retrieve.

Errors