How payments work

The Payment and PaymentSession objects, payment statuses, and which integration to pick.

Two objects drive every one-off payment:

  • A Payment is the money: an amount, a currency, a status, and the outcome details (card brand, last four digits, failure reason, refunded amount). Its id starts with pay_.
  • A PaymentSession is the checkout that collects it: which payment methods are offered, where to send the payer afterwards, the language, and whether it is hosted or embedded. Its id starts with ps_.

Creating a session with an amount creates the payment for you. That is the normal path. You can also create a payment first and attach a session to it with payment, for example to keep one payment id across a retried checkout.

Lifecycle

POST /v1/payment_sessions  →  Payment: created, Session: open
payer completes checkout    →  Payment: succeeded | failed, Session: complete
24 hours pass unpaid        →  Session: expired
POST /v1/refunds            →  Payment: refunded_amount grows, then status refunded

Payment status

StatusMeaning
createdAwaiting the payer. Also the state of a bank invoice until the bank confirms payment.
processingAuthorised, awaiting final confirmation from the processor. Brief for cards.
succeededCharged. Fulfil the order.
failedDeclined or authentication failed. failure_reason says why. The payer can try again in the same session.
canceledCancelled before completion.
refundedFully refunded. Partial refunds keep succeeded and increase refunded_amount.

Session status

StatusMeaning
openThe payer can still pay. Sessions live for 24 hours.
completeA payment attempt finished, or a bank invoice was issued.
expiredNobody paid within 24 hours. Create a new session.

Amounts and currencies

Amounts are integers in the currency's smallest unit, paired with an ISO 4217 currency. Icelandic króna has no minor unit in circulation, so 1990 is 1.990 kr. Euro and the other currencies use cents: 1990 is €19.90. Supported currencies:

ISK (no minor unit), EUR, USD, GBP, DKK, NOK, SEK

Amounts must be at least 1 and at most 2,000,000,000.

Hosted or embedded?

HostedEmbedded
Where the payer payscheckout.borga.isA modal on your page, loaded by borga.js
IntegrationOne server call and a redirectServer call plus a few lines of browser code
Payment methodsCards, wallets, bank invoiceCards and wallets
Needs a publishable keyNoYes
Best forMost shops, invoices, links you send by emailCheckouts that must not leave the page

Both use the same session object and the same webhooks. Start with hosted checkout; switch to embedded if you need it.

Fulfilment: webhooks, not redirects

The redirect back to your return_url tells you the payer finished the checkout UI, nothing more. A bank invoice is paid days later, a slow 3-D Secure flow may still be settling, and a payer can close the tab before the redirect. Fulfil from the payment.succeeded webhook and use the return page only to show status. See Webhooks.

Saving cards and subscriptions

A session can ask Borga to save the card for later (save_payment_method: true) or start a subscription when it succeeds (subscription). Both attach the card to a Customer as a PaymentMethod. See Saved cards and Subscriptions.

Invoices

When a payment succeeds and you have an accounting provider connected, Borga books a paid sales invoice there and links it to the payment as an Invoice object. Refunds produce credit notes. See Invoicing.