Skip to content

maxanapay.js

The production major channel is published at

https://js.maxanapay.com/v1/maxanapay.js. Load it directly from that URL; do not copy or re-host the bundle. It supports the PayPal wallet rail described under What v1 does not do. Use Hosted Checkout or Embedded Checkout when the session needs an excluded rail or capability.

The v1 channel currently serves this exact release:

1.1.0 — SHA-256

13516a48762a0938120d70c1aac68884e2ed90112997609310c4af0e600dd3ca

The capability and eligibility behavior on this page describes those published bytes.

This page is the single shared reference for the checked SDK contract. The direct merchant and channel tutorials each explain where browser checkout belongs in that reader’s journey.

The published browser SDK accepts these options:

  • sessionIdstring (required)
  • containerstring | HTMLElement (required)
  • environmentMaxanaEnvironment (optional)
  • apiBasestring (optional)
  • onApproved(payment: MaxanaPayment) => void (optional)
  • onCancel() => void (optional)
  • onError(error: MaxanaCheckoutError) => void (optional)
  • styleMaxanaButtonStyle (optional)
  • localestring (optional)

Configure either environment or apiBase, and allow the corresponding API origin.

The list above marks each of the two optional, which is true of each one alone and misleading about the pair: one of them is required. environment takes live or sandbox and resolves the API origin for you. apiBase overrides it, and exists for pointing at a backend that is neither — a local one, typically. Supplying neither throws config_error before anything mounts, so a page that omits both fails on its first load rather than at payment time.

Keep session creation and all secret-key calls on your server. The browser may receive the session identifier, but never the secret used to create it.

Handle onApproved, onCancel, and onError as UI events. Confirm the durable result through your backend and design error handling around the exported SDK error codes.

The list under Contract is authoritative for option names and required fields. Unknown options are configuration mistakes; do not infer a feature from a draft or an internal type that is absent from this reference.

The checked v1 option contract includes locale and style controls. This sample uses only documented option names and accepted values:

Configure and mount a styled checkout
MaxanaPay.checkout({
  sessionId: 'cs_0123456789abcdef0123456789abcdef',
  environment: 'live',
  container: '#paypal-buttons',
  locale: 'pt_BR',
  style: {
    layout: 'vertical',
    color: 'blue',
    shape: 'pill',
    label: 'pay',
    height: 45,
  },
  onApproved(payment) {
    window.location.assign(`/orders/${payment.orderId}`);
  },
});

The SDK’s buyer-safe order calls follow the curated payment-operation contract. Order creation identifies direct mode and the checkout page’s exact origin; capture also identifies the checkout session. These headers are browser context, not authentication, and never replace the server-side key used to create the checkout session.

The direct order contract rejects an unrecognized field with 422 instead of ignoring it. Construct buyer-safe request bodies from the documented schema and keep merchant-only values on your server.

The source descriptions for these requirements are published with POST /api/payments/orders and POST /api/payments/orders/{order_id}/capture in the operation reference. The declared security alternatives include anonymous buyer calls; do not add a merchant or channel secret to them.

For direct checkout, the order-creation contract requires checkout_page_url. It must be HTTPS, match the calling page’s exact allowed origin, and is used for the provider return and cancellation paths. Initialize checkout on every load of that page so a returning buyer resumes the SDK flow. Treat the resulting browser callback as experience feedback until your server reconciles durable payment state.

Use onApproved to update the interface and make fulfilment idempotent, but do not treat the callback as a settlement record. Persist and reconcile the order or transaction identifier through your backend and duplicate-safe webhooks.

onApproved receives one object with these fields:

FieldType
orderIdstring
captureIdstring | null
statusstring
amountnumber | null
currencystring | null
methodstring | null
buyerEmailstring | null
capturedAtstring | null
source'capture' | 'session'

Three of them are worth reading before the rest.

captureId is the identifier a refund is addressed by — the same value the API calls provider_capture_id, and the same one POST /api/payments/captures/{capture_id}/refund takes in its path. It is the only place this identifier reaches the browser. It is null whenever the money has not been taken, so check status before storing it.

status is the provider capture status, lowercased: captured means the money was taken and approved means it was not.

source says where the object came from. capture means this page just took the payment. session means the session was already paid when the SDK loaded — a buyer who reloaded or returned — and nothing was charged now. orderId is stable across both, so fulfilment keyed on it is safe either way; a counter incremented on every callback is not.

The nullable fields are nullable for a reason rather than by accident: the already-paid session carries the buyer-safe view of the payment, which has no buyer email, no amount, and no method. Read those from your own record or from the payment.captured event instead of inferring them here.

Use the shared SDK error vocabulary. Developer messages are not buyer copy, and an unknown code must fall back to a generic failure path.

This portal does not create a payment session for a live demonstration. Exercise the published SDK with a server-created sandbox session, then repeat your launch checks with live credentials and origins before accepting production traffic.

The checked v1 contract excludes card fields and 3-D Secure orchestration, Apple Pay, Google Pay, Pay Later messaging, App Switch, SDK-controlled shipping and billing-address collection, save-payment-method sessions, and Gr4vy or NMI sessions.

Those published bytes refuse to mount the PayPal wallet rail only when the checkout session is routed to a provider other than

ppcp or is a save-payment-method session with vault_setup. Those two cases report provider_unsupported.

A ppcp session still proceeds to the PayPal button mount when it requests SDK-controlled shipping collection or includes an unrecognized funding name. Proceeding does not add the omitted capability: this SDK does not collect the shipping address, and only recognized funding names are passed to PayPal. PayPal can still report later that no funding source is eligible for this buyer and session; that provider result also reports provider_unsupported.

Pay Later buttons and Pay Later messaging are separate capabilities. A Pay Later button may appear when the session advertises it and PayPal finds the buyer eligible; promotional Pay Later messaging is not rendered. Buyer-visible buttons vary by merchant eligibility, session funding sources, and buyer, so do not design for a fixed button count.

For card fields, 3-D Secure, Apple Pay, Google Pay, Gr4vy, or NMI today, use the hosted or embedded checkout returned by the same checkout session.

Legacy section links remain anchored here:

Follow the content security policy guidance for the production presentation you actually deploy. Add only the published SDK URL you load.

Use the SDK release and versioning policy. A configured major-channel URL receives compatible v1 updates; use a ledger-recorded exact version when your release process requires byte-level pinning.