Skip to main content

Choose your integration

This is the first decision, and everything else in these docs hangs off it.

It is not "what kind of company are you". It is:

How much of payment collection do you want Wasp to own?

Collection means the part where a customer actually hands over a payment method: the card form they type into, the Google Pay™ or Apple Pay sheet, the encryption, the browser plumbing behind it. It is not the same thing as processing — sending the collected payment to be authorised and getting an answer. Wasp always owns processing. Collection is the part you get to choose.

There are four paths, grouped under three questions. The first question has a smaller choice inside it, which is why you will sometimes see them counted as three.

1. LET WASP OWN COLLECTION
│
├── Hosted Checkout
│ The customer pays on a Wasp page. You send them there and get a result.
│
└── Embedded Checkout
The customer stays on your page. The Wasp Checkout SDK collects.
├── Drop-in Wasp arranges the whole payment area for you
└── Headless You arrange the page; Wasp mounts each control into it

2. KEEP THE COLLECTION YOU ALREADY HAVE
│
└── Client-owned collection
Your own checkout collects, with no Wasp browser code at all.
Wasp prepares the payment method, you collect it, Wasp processes it.

3. THERE IS NOTHING TO COLLECT
│
└── Direct Payment API
You already hold the card, token or stored credential — from a
customer's saved payment method, a subscription, or a back-office
process. There may be no browser involved at all. You submit the
payment to be processed.

The third answer surprises people, so it is worth saying plainly: not every payment starts with a customer typing something. A subscription renewal, a saved card charged at dispatch, an invoice settled by your operations team — these have no collection step, because collection already happened. That is a legitimate Wasp integration, not a workaround.

Whichever you choose, the payment ends up in the same place: one payment call, made by your backend. There is no separate payment API per integration model, and none per payment method. The exact route, its request and its response are in the Merchant API reference and the implementation guides, which open once you have been granted access.

Which one is for you​

If this sounds like youChoose
I want payments working with the least code, and I do not need the payment step to look like my siteHosted Checkout
I want the customer to stay on my page, and I would rather not build payment UIEmbedded Checkout — drop-in
I want the customer to stay on my page, and I want to control the layout myselfEmbedded Checkout — headless
I already have a checkout that collects cards or wallets, and I want Wasp to process the paymentsClient-owned collection
I am a payment service provider with my own checkout serving my own merchantsClient-owned collection
I already hold a card, token or stored credential and just need it processedDirect Payment API
I am charging a saved payment method for a subscription, renewal or repeat orderDirect Payment API

A payment service provider is the clearest example of the last row, but it is not a different product and it is not a different API. A merchant with a mature checkout of its own chooses exactly the same path for exactly the same reason.

Words used throughout these docs​

Read these once. They are used with these meanings on every page.

  • Browser — the customer-facing page and its JavaScript. Never holds an API key or a signing key.
  • Your backend — your server. This is where Wasp credentials live, and the only place that signs a Wasp request.
  • Server-to-server — a call your backend makes to Wasp directly. Not a call made by browser JavaScript.
  • reference — your identifier for the payment. You choose it, you send it, every result and lookup is keyed by it. There is no second payment id.
  • Payment method — Card, Google Pay, Apple Pay. What the customer pays with.
  • Payment instrument — what collection produced, in one shape whatever the customer paid with. Part of it is sealed: you forward it to your backend unchanged and never open it.
  • Checkout Web Domain — a domain Stratsol has authorised your Wasp checkout to run on. One list, whatever payment methods you use.
  • Return URL — somewhere a customer's browser can land after paying. It is a navigation destination and never proof that a payment succeeded.

1. Let Wasp own collection​

Hosted Checkout​

Your backend registers a checkout, Wasp gives you a URL, you send the customer there. Wasp owns that page completely — the payment methods, the card form, the wallet sheets, the authentication step if the payment needs one.

your backend registers the checkout with Wasp (server-to-server, signed)
↓
you redirect the customer to the Wasp page
↓
Wasp collects and processes the payment
↓
Wasp shows the customer the result, on the Wasp page
↓
the customer MAY choose "Return to merchant" — they may not
↓
your backend confirms the real result by reference,
or acts on the signed outcome notification

You write no browser payment code. You do not load the Wasp Checkout SDK.

The payment ends on the Wasp page, not on yours. Wasp shows the customer the terminal result there and offers a link back to you. Following it is their choice, and a satisfied customer often just closes the tab — so build for a return that never arrives. Anything in that return URL is informational. Confirm by reference from your backend, or act on the signed outcome notification, before you fulfil anything.

Guide: Hosted Checkout.

Embedded Checkout​

The customer never leaves your page. Your backend starts a checkout and receives one short-lived value; your page hands that value to the Wasp Checkout SDK, and the SDK does the collecting.

your backend starts the checkout with Wasp (server-to-server, signed)
↓ returns one short-lived value for the browser
your page gives that value to the Wasp Checkout SDK
↓
the SDK collects a payment instrument in your page
↓
your page hands the instrument to YOUR backend
↓
your backend submits the payment to Wasp, signed

The page states nothing about the payment — not the merchant, not the amount, not the currency, not the reference. All of that was fixed by the call your backend made, which is why a customer cannot edit it.

Guide: Embedded Checkout.

Drop-in​

You give the SDK one container. It writes the whole payment area: every payment method your merchant has enabled, laid out and styled, in the light or dark presentation you asked for.

What that means in practice: you place one empty container on your page, hand the SDK the value your backend returned, and give it one function to call when it has collected something — which forwards the result to your own backend. The SDK does everything between: drawing the payment methods, collecting, submitting, closing the wallet sheet, and telling you the outcome. There is no second button to wire up and no branch per payment method.

The working code, with every option explained line by line, is in Drop-in.

Headless​

You build the layout — headings, order, spacing, your own copy — and tell the SDK where each control goes.

What that means in practice: you create the checkout once, describe how a collected payment should be submitted and what to do with the result, and then mount each control — the Google Pay button, the Apple Pay button, the card fields — into elements you have positioned yourself.

The working code, with every option explained line by line, is in Headless.

Headless does not mean "no Wasp payment UI". The SDK still renders the card fields, still renders the wallet buttons, still does the collecting, and still finishes the payment its controls start. What you get back is control of the layout around them.

2. Keep the collection you already have​

Client-owned collection. Your checkout stays yours. You load no Wasp browser code, you hold no Wasp key in the browser, and you keep collecting exactly the way you collect today. Wasp prepares each payment method server-to-server, you collect, and you submit the result to the same processing call everyone else uses.

your backend asks Wasp to prepare a payment method (server-to-server, signed)
↓
your own checkout collects it — your form, your wallet button, your page
↓
your backend submits the result to Wasp, signed

The sequence does not change when the payment method changes. Preparing Card, Google Pay and Apple Pay is the same call with a different value in it.

Guide: Client-owned collection.

3. There is nothing to collect​

Direct Payment API. You already hold the payment credential, so there is no collection step to own or delegate. Your backend submits the payment to the same processing call every other model ends at, and Wasp processes it.

you already hold the card, token or stored credential
↓
your backend submits the payment to Wasp, signed
↓
Wasp processes it and answers

There is no Wasp browser code, no payment page and — often — no browser at all. A subscription billing run has no customer present to look at anything.

Two things make this a distinct path rather than a shortcut through the others:

  • You supply the credential directly. The same payment call accepts either a card, token or stored credential you already hold, or the instrument Wasp collection produces. Same call, same result; you provide the first rather than receiving the second.
  • Repeat payments are explicit. When you charge a credential the customer stored earlier, you say so on the payment, and link it back to the payment that set the series up. That is what tells Wasp this is a stored-credential payment rather than a fresh one, and it changes how it is presented to the card scheme.

This path carries obligations the others do not. Holding card data yourself brings PCI DSS scope, and charging a stored credential requires that you took the customer's agreement when you stored it. Wasp processes what you submit; it cannot supply a mandate you did not obtain. If you would rather not hold card data at all, one of the first two models keeps it out of your systems.

Guide: Payment API overview.

Headless is not client-owned collection​

These two get confused, because "headless" sounds like "you own it". They are different in the one way that matters:

Embedded headlessClient-owned collection
Does your page load the Wasp Checkout SDK?YesNo
Who renders the card fields and wallet buttons?The Wasp SDKYou
Who encrypts a card in the browser?The Wasp SDKYou already do, however you do it today
Who runs collect → submit → close the wallet sheet?The Wasp SDKYou
Who owns the layout around the controls?YouYou
What starts it?Your backend starts an embedded checkoutYour backend asks Wasp to prepare a payment method

Headless gives you the layout. Client-owned gives you the collection.

If you have no existing card-collection capability, headless is almost certainly what you want: Wasp collects the card, so the card never lands in your systems.

What is the same in all four​

This is the point of integrating with Wasp once.

  • One payment call, made by your backend, whichever model you chose.
  • One payment identity. Your reference, chosen by you, on everything.
  • One authentication model. Requests are signed by your backend. Browser code never holds a key.
  • One result model. 200 means Wasp decided — read payment.approved, and do not treat HTTP 200 as approval. 202 means Wasp accepted the payment and has not decided it: read status, because authentication_required carries an action for the customer and processing carries none and needs nothing of them. Either way the signed outcome notification finishes it, a failed authentication (W1) and an abandoned one (W2) included; a single lookup by reference recovers a notification that did not reach you. See Payment outcomes.
  • Payment methods are data, not new integrations. Adding Google Pay or Apple Pay to a merchant does not change the calls you make or the order you make them in.
  • You never open a wallet payload. Whatever the wallet gave you is forwarded unchanged. Wasp decrypts it. You never receive, store or operate the keys that could.

What you have to build​

The real question behind the choice. Each of these is your side of the line.

Hosted Checkout​

You build: one signed server call to register the checkout, a redirect, and a server-side confirmation by reference. That is the whole integration.

Wasp owns: the payment page, every control, collection, the provider interaction, customer authentication, and the payment itself.

Embedded Checkout — drop-in​

You build: one signed server call to start the checkout, a container on your page, a route on your backend that submits the payment, and a route that receives Wasp's signed outcome notification — the result of any payment Wasp accepted but could not decide in your request. That is either 202 shape: one waiting on the customer, and one Wasp completes on its own with nothing asked of them.

The Wasp SDK owns: the layout inside the payment area, the controls, collection, browser encryption, when the payment is submitted, closing the provider's sheet, and the completion event.

Embedded Checkout — headless​

You build: your page layout, the elements each control mounts into, the surrounding experience, and the same backend routes as drop-in — start, submit, and receive the outcome notification.

The Wasp SDK owns: the payment controls themselves, collection, browser encryption, the armed lifecycle, and provider completion. Exactly as in drop-in — you gained the layout, not the payment machinery.

Client-owned collection​

You build: your page, your payment controls, your own provider and browser collection, the signed call to Wasp's generic preparation, the signed submission of what you collected, a route that receives Wasp's signed outcome notification for either 202 shape, and — when one of them asks for the customer — a link that opens Wasp's page in a new tab.

Wasp owns: preparation, the Wasp and provider credentials, decryption of anything a wallet encrypted, customer authentication, processing, and the result.

Direct Payment API​

You build: the signed submission of a card or stored credential you already hold, and a lookup by your reference for the rare payment whose answer never reached you.

Wasp owns: processing and the result. For the published examples, which use entry: "Manual", that result comes back in the response: a keyed card has no browser, so there is no authentication step and no notification to receive.

That is a property of those examples, not of the API. The same Direct call sent with a browser entry type such as "Digital" — including a stored-card charge you start — can be answered 202 and completes through a signed outcome notification like any other. If you use one, configure a callback and handle both 202 shapes. Holding card data brings obligations the other models keep away from you.

At a glance​

HostedEmbedded drop-inEmbedded headlessClient-ownedDirect
Payment pageWaspYouYouYouNone
Payment-area layoutWaspWaspYouYouNone
Card fields / wallet buttonsWaspWaspWaspYouNone
Browser card encryptionWaspWaspWaspYours, or raw card details over your signed backend callNone — you hold the card
Collect → submit → close the sheetWaspWaspWaspYouSubmit only
Amount, currency, referenceYour backendYour backendYour backendYour backendYour backend
Submitting the payment to WaspWaspYour backendYour backendYour backendYour backend
Wallet decryptionWaspWaspWaspWasp—
Customer authentication (3DS)Wasp, end to endWasp, SDK opens the stepWasp, SDK opens the stepWasp, you open the stepNot for the Manual examples; possible with a browser entry type
How your backend learns the resultOne check by reference, or a notification — not the customer's returnThe response, or a signed notificationThe response, or a signed notificationThe response, or a signed notificationThe response; a signed notification if you use a browser entry type

Customer authentication, in each model​

Some payments need the cardholder to prove who they are before they can be approved. Wasp runs that authentication in every model. What differs is only how much of the browser journey you write.

ModelWhat you do
HostedNothing. The Wasp page runs it, then shows the result and offers a link back. You never see a 202.
EmbeddedYour backend tells the SDK in its own vocabulary: { "paymentStatus": "actionRequired", "action": { "url": … } } when the 202 carries an action — the SDK opens it — or { "paymentStatus": "processing" } when its status is processing and nothing is asked of the customer. Do not pass Wasp's 202 body through unchanged: it has no paymentStatus, so the SDK reports failed. See What your backend returns to the browser. Either way the result arrives at your backend as a signed notification.
Client-ownedOpen the action in a new tab from your page. The result arrives at your backend as a signed notification.
DirectNothing for the Manual examples. With a browser entry type, as for client-owned.

The payment is never resubmitted. A 200 is the result; after a 202 the result arrives as a signed notification. A lookup by reference is only for recovering a result whose one notification attempt did not reach you, including a W1 failed authentication or a W2 abandonment. See Customer authentication.

Next​