Skip to content
JuicePay

JuicePay documentation

Create account

Documentation

POST

Payment intents

Create and manage inbound payments.

A payment intent represents money you expect to receive. It is the correct primitive whenever a customer is involved, because it constrains what they can send and where.

Create#

bash
curl -s -X POST "$JUICEPAY_URL/v1/payment_intents" \
  -H "Authorization: Bearer $JUICEPAY_KEY" \
  -H "Idempotency-Key: order:ord_8812:intent" \
  -d '{
    "amount": "4250.00",
    "asset": "USDC",
    "reference": "INV-2291",
    "description": "Consulting retainer, August",
    "accepted_chains": ["base", "solana", "arbitrum"],
    "settle_to": { "asset": "USDC" },
    "expires_in": 3600,
    "metadata": { "customer_id": "cus_4471" }
  }'
json
{
  "id": "pi_9fK2xQ",
  "object": "payment_intent",
  "status": "requires_payment",
  "amount": "4250.00",
  "asset": "USDC",
  "amount_received": "0.000000",
  "reference": "INV-2291",
  "hosted_url": "https://pay.juicepay.test/pi_9fK2xQ",
  "client_secret": "pi_9fK2xQ_secret_7mK2",
  "accepted_chains": ["base", "solana", "arbitrum"],
  "created": "2026-08-19T09:14:02Z",
  "expires_at": "2026-08-19T10:14:02Z"
}

Parameters#

ParameterRequiredNotes
amountYesDecimal string. Minimum varies by asset and chain.
assetYesAsset you are pricing in.
referenceRecommendedYour own identifier; used for reconciliation and search.
accepted_chainsNoDefaults to your account allowlist. Restrict it where you can.
settle_toNoConvert on settlement into a different asset.
expires_inNoSeconds until expiry. Defaults to 3600.
metadataNoUp to 20 key-value pairs, each under 500 characters.

Statuses#

StatusTerminalMeaning
requires_paymentNoAwaiting the payer.
processingNoSeen onchain, not yet final.
partially_paidNoLess than the requested amount received.
succeededYesFully paid and final.
succeeded_lateYesPaid after expiry.
expiredYesNo payment before expiry.
revertedYesReorg removed a payment previously announced as succeeded.
canceledYesCancelled by you before payment.

Retrieve and update#

bash
curl -s "$JUICEPAY_URL/v1/payment_intents/pi_9fK2xQ?expand[]=ledger_entries" \
  -H "Authorization: Bearer $JUICEPAY_KEY"

Only metadata, description, and accepted_chains are mutable, and only while the intent is requires_payment. Changing accepted chains after a payer has begun will not reject an in-flight transfer.

Cancel#

bash
curl -s -X POST "$JUICEPAY_URL/v1/payment_intents/pi_9fK2xQ/cancel" \
  -H "Authorization: Bearer $JUICEPAY_KEY"

Cancelling prevents further payment. It does not recall funds already sent.

List#

bash
curl -s "$JUICEPAY_URL/v1/payment_intents?status=succeeded&created_gte=2026-08-01" \
  -H "Authorization: Bearer $JUICEPAY_KEY"

Underpayment tolerance#

By default any shortfall produces partially_paid. Set a tolerance to accept small differences, which is common when the payer is converting from a volatile asset:

json
{ "underpayment_tolerance_percent": "1.0" }

Within tolerance, the intent reaches succeeded with the actual amount_received recorded. Outside it, the intent stays partially_paid and you decide what to do — refund, request the difference, or accept it manually.

Events#

EventFires when
payment_intent.processingValue seen onchain.
payment_intent.succeededPayment is final.
payment_intent.partially_paidShortfall outside tolerance.
payment_intent.expiredExpiry reached unpaid.
payment_intent.revertedA previously announced payment was reorganised away.
payment_intent.unsupported_chainPayer used a chain you did not accept.
payment_intent.canceledCancelled by you.