Integration guides
Build a transaction
A transaction holds what the buyer pays for. Build it as a draft, finalize it to freeze the amounts, then collect it with a checkout session.
On this page
When to build the transaction yourself#
A checkout session can create the transaction for you from transactionDraft. Build the transaction yourself when you want to:
- Show the final amount and the tax before the buyer goes to checkout.
- Attach a stored customer or a billing address.
- Apply a promotion code.
- Keep your own reference and metadata on the transaction.
You need an API key with transactions:write and transactions:read. See Transactions for the model.
Create a draft#
Send either lines or amount, not both.
lines: each line names acatalogPriceIdand aquantity. Merxian takes the name, the unit amount, and the tax code from the catalog. You cannot send your own description or unit amount.amount: one gross amount in minor units, with no lines. An account on which Merxian calculates tax cannot useamount. Such a request returns422with the codeamount_only_not_allowed.
curl -X POST https://api.merxian.com/v1/transactions \
-H "Authorization: Bearer $MERXIAN_API_KEY" \
-H "Idempotency-Key: 9b3f6c1e-2a47-4d8b-b5e0-7c1d2e3f4a5b" \
-H "Content-Type: application/json" \
-d '{
"currency": "EUR",
"lines": [{ "catalogPriceId": "price_4Wm9TqLz2Xb7KdN8r", "quantity": 1 }],
"customerId": "cus_2Lp7XcN4vB8mQ1tKd",
"billingAddress": {
"line1": "Torstraße 1",
"city": "Berlin",
"postalCode": "10119",
"country": "DE"
},
"externalReference": "A-1042",
"metadata": { "order_ref": "A-1042" }
}'The response is a transaction with status: "draft" and revision: 1. amounts holds subtotal, discount, net, tax, and total in minor units. A total of 14280 in EUR is €142.80. See POST/v1/transactions.
The buyer fields#
| Field | Use it for |
|---|---|
customerId |
A stored customer of your account, cus_…. |
buyer |
Buyer details for this transaction only: email, name, country, customerType, vatId, phone. Values in buyer override the stored customer values. |
billingAddress |
The billing address: line1, city, postalCode, and country are required. |
promotionCode |
A promotion code of your account. It needs lines. |
externalReference |
Your own reference, for example a reference number from your own system. |
metadata |
Your own key-value pairs. At most 50 entries, keys up to 64 characters, values up to 1024 characters. |
Preview the amounts#
POST/v1/transactions/preview takes the same body as create. It returns the transaction that
the request would create, with its tax and discounts, and stores nothing. It needs only
transactions:read and no Idempotency-Key. Use it to show a price summary before you create the
transaction.
Update a draft#
PATCH/v1/transactions/{transactionId} replaces the commercial content of a draft. Send the full
content again, not only the changed fields.
To prevent lost updates, send the revision that you last read. Use the If-Match header with the weak form W/"<revision>", or the expectedRevision field.
curl -X PATCH https://api.merxian.com/v1/transactions/txn_0F8mQ2rXbT4kL9pZa \
-H "Authorization: Bearer $MERXIAN_API_KEY" \
-H 'If-Match: W/"1"' \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"currency": "EUR",
"lines": [{ "catalogPriceId": "price_4Wm9TqLz2Xb7KdN8r", "quantity": 2 }],
"customerId": "cus_2Lp7XcN4vB8mQ1tKd"
}'If the transaction changed after that revision, the request returns 409 with the code revision_conflict. Read the transaction again, apply your change to the new content, and send the update with the new revision.
You cannot change a draft from lines to amount, or from amount to lines. Create a new transaction instead.
Finalize#
POST/v1/transactions/{transactionId}/finalize moves the transaction from draft to ready. Merxian
calculates the final amounts, discounts, and tax, and freezes them with the buyer and line details.
curl -X POST https://api.merxian.com/v1/transactions/txn_0F8mQ2rXbT4kL9pZa/finalize \
-H "Authorization: Bearer $MERXIAN_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"Finalize can return 422 with the code invalid_transaction when the draft is not complete. For example:
- When Merxian calculates tax, it needs the buyer country. Send
buyer.country, a customer with a country, or abillingAddress. - When Merxian issues the invoice, the transaction needs a buyer and a billing address.
- All lines must use the currency of the transaction. Otherwise the code is
currency_mismatch.
Read message, complete the draft with an update, and finalize again. You receive transaction.ready after a successful finalize.
Collect the transaction#
Create a checkout session with the transactionId. The session can take a draft or a ready transaction.
curl -X POST https://api.merxian.com/v1/checkout-sessions \
-H "Authorization: Bearer $MERXIAN_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"transactionId": "txn_0F8mQ2rXbT4kL9pZa",
"successUrl": "https://shop.example.com/checkout/success",
"cancelUrl": "https://shop.example.com/checkout/cancel",
"clientReferenceId": "A-1042"
}'Continue with Accept a payment with hosted checkout.