Standard order
The payment and order step for the Standard flow. These calls are on the payment host https://cc.firmly.work and require the x-firmly-authorization header. {domain} is the merchant domain, e.g. staging.luma.gift.
Encrypt the card first
The card is never sent in the clear. Fetch the merchant’s public key, then JWE-encrypt the card details inside your own process and send the resulting token as encrypted_card.
GET /api/v1/payment/key→ the public key (Get Public Key).- Encrypt the card as a JWE with that key.
- Send the JWE as
encrypted_cardin the calls below.
Place an order (one-shot)
POST /api/v1/payment/domains/{domain}/place-order
Builds the cart from items and pays in a single call — the “buy now” path when you already know exactly what the shopper wants.
encrypted_card(string, required) — the JWE token.shipping_info(object, required) — shipping address.billing_info(object, required) — billing address.items(array, required) — each{ "variant_id": "...", "quantity": 1 }.captcha_token(string, optional) — bot-protection token when required.
curl --request POST \--url https://cc.firmly.work/api/v1/payment/domains/staging.luma.gift/place-order \--header 'Content-Type: application/json' \--header 'x-firmly-authorization: YOUR_TOKEN' \--data '{"encrypted_card": "<JWE>","shipping_info": { "first_name": "Ada", "last_name": "Lovelace", "email": "ada@example.com", "phone": "5125550100", "address1": "1 Infinite Loop", "city": "Austin", "state_or_province": "TX", "country": "US", "postal_code": "78701" },"billing_info": { "first_name": "Ada", "last_name": "Lovelace", "email": "ada@example.com", "phone": "5125550100", "address1": "1 Infinite Loop", "city": "Austin", "state_or_province": "TX", "country": "US", "postal_code": "78701" },"items": [ { "variant_id": "24-MB05", "quantity": 1 } ]}'
Response — the placed cart, cart_status: "submitted", carrying platform_order_number, submitted_at, and the confirmed totals.
Complete an existing cart
POST /api/v1/payment/domains/{domain}/complete-order
Pays for and finalizes the cart you already built through the cart and checkout steps — the incremental path.
encrypted_card(string, required) — the JWE token.billing_info(object, required) — billing address.captcha_token(string, optional).
curl --request POST \--url https://cc.firmly.work/api/v1/payment/domains/staging.luma.gift/complete-order \--header 'Content-Type: application/json' \--header 'x-firmly-authorization: YOUR_TOKEN' \--data '{"encrypted_card": "<JWE>","billing_info": { "first_name": "Ada", "last_name": "Lovelace", "email": "ada@example.com", "phone": "5125550100", "address1": "1 Infinite Loop", "city": "Austin", "state_or_province": "TX", "country": "US", "postal_code": "78701" }}'
Response — the completed cart, cart_status: "submitted", carrying platform_order_number, submitted_at, and the confirmed totals.
Errors
Errors return { code, error, description }; program against error. Common cases: InvalidInputBody (400, missing encrypted_card / addresses / items), CartNotFound (404, on complete-order with no cart), payment declines. See Errors & Conventions for the full catalog.