With PayPal Card Fields, the customer types their card on your own checkout page, inside fields that PayPal hosts. Card details go straight to PayPal and never pass through your server or Admoji. Your site creates the PayPal order, and once the customer approves it, you send the order to Admoji. Admoji creates the CRM order and captures the payment once.
Step 1: Create the PayPal Order on Your Server
Render PayPal Card Fields with the PayPal JS SDK and create the order from your server with:
intentset toCAPTURE, with one purchase unit and the card as payment source.A
custom_idon the purchase unit with a unique checkout reference you generate for this payment. You send the same value to Admoji in Step 2.The exact amount and currency Admoji will charge: product or variant prices (or the
AmountandShipAmountyou send for each product), shipping and sales tax included.To save the card for upsells and rebills,
payment_source.card.attributes.vault.store_in_vaultset toON_SUCCESS, with the customer's consent. Leave the merchant customer ID empty. If you need to set one, it must beadmoji.{AccountID}.{CustomerID}(ask support for your account ID); with any other value Admoji refuses the order.
onApprove, do not capture the order. PayPal allows only one capture per order, and Admoji can only take an approved order that has not been captured yet. Send the order ID to Admoji instead.POSSIBLE, or NO with enrollment status N, U or B. Otherwise Admoji refuses it and nothing is charged.Step 2: Send the Approved Order to Admoji
Create the customer first with POST /api/v2/open/customers, as for any other order. Then call the capture endpoint with your Paypal Checkout key and an Idempotency-Key header:
$ curl -X POST 'https://openapi.admoji.com/api/v1/open/payments/paypal/v2/orders/capture' \
-H "content-type: application/json" \
-H "Idempotency-Key: 6f1c2b7e-checkout-1001" \
-H "Authorization: ApiKey pk_paypal_492796e421a34666a5695d53cd311111" \
-d '{
"OrderID": "5O190127TN364715T",
"CustomerID": 8563080,
"SiteID": 1004000,
"ProcessorID": 7890,
"Products": [ { "ProductID": 11115, "Quantity": 1 } ],
"CheckoutReference": "checkout-1001"
}'
OrderID— the approved PayPal order ID.CustomerID,SiteIDandProcessorID— the Admoji customer, campaign and PayPal processor.Products— the products and quantities of the order.CheckoutReference— the same value you put incustom_id.
Do not send CrmOrderID or PaySource in this call.
{ "CrmOrderID": 10231111, "PaypalOrderID": "5O190127TN364715T", "CaptureID": "3C679366HH908993F", "State": "Completed",
"VaultStatus": "VAULTED", "VaultReady": true, "Status": 0, "DeclineReason": null }
Step 3: Handle the Result
Status 0 — the payment was captured and the order is approved.
VaultReadytells you whether the card was saved for future charges.Status 1 with
StateDeclined— the card was declined.DeclineReasonhas PayPal's code, for exampleINSTRUMENT_DECLINED. For a new attempt, create a new PayPal order with a new checkout reference.Status 1 with
Good: falseand anErrorMessage— Admoji refused the request before charging anything (for example, a total that does not match, a processor that cannot read the order, or a cancelled customer). Fix the cause and create a new PayPal order.Status 2, a timeout or HTTP 409 — the result is not final yet. Send the same request again, with the same
CheckoutReference, until you get Status 0 or 1. Never create a new checkout to resolve an uncertain payment.
ErrorMessage names the total Admoji expects, for example …does not match the CRM order total of 53.11 USD. Create a new PayPal order for that amount.Step 4: Confirm a Card Saved Later (Optional)
If PayPal saves the card after the payment, it sends you a VAULT.PAYMENT-TOKEN.CREATED webhook. Forward its event ID to Admoji with the same key, so the customer's rebills can start:
POST https://openapi.admoji.com/api/v1/open/payments/paypal/v2/orders/vault/confirm
{ "OrderID": "5O190127TN364715T", "ProcessorID": 7890, "EventID": "WH-58D329510W468432D-8HN650336L201105X" }
Until the card is confirmed, the customer's subscriptions stay on hold.
Step 5: Charge an Upsell with the Saved Card
Call POST /api/v1/open/payments/paypal/v2/orders/unified with PaySource 3, the CustomerID, SiteID, Products, ProcessorID and a new CheckoutReference. The customer does not enter the card again. Reuse the reference only to retry a Status 2, timeout or 409 result; a declined upsell needs a new reference.
How Rebills Work
Rebills charge the saved card automatically, always on the PayPal processor that saved it.
Refund these orders from Order Details, as any other order. Partial refunds work up to the amount paid.
If the customer's card on file is replaced with a non-PayPal payment method, the rebill is refused. Move the subscription to another processor from Continuity, or have the customer save a new card through Card Fields.
In the customer profile, Recurrings shows a Check PayPal payment icon on these subscriptions. Use it when a rebill is still pending: it asks PayPal for the result and never charges again. While a payment is pending, Run Recurring is hidden.
If PayPal never received a manual rebill, Check PayPal payment offers Retry payment, which resends the original request and cannot charge twice.
Related articles