Skip to main content
Use this page for a one-time charge. The shopper picks Pay with FSA/HSA, your server creates a Gale checkout, and Gale hosts the card page. Gale writes the payment record to your Stripe account with the restricted key from Step 2. This option does not create a Stripe PaymentIntent or Charge. Card payments on the same page can keep theirs.

Prerequisites

  • An existing checkout that mounts Stripe’s Payment Element.
  • Stripe Dashboard access, with permission to create a custom payment method.
  • Gale Merchant Dashboard access, and a Gale API key (glm_test_… / glm_live_…).
Card payments on the same page can keep their own PaymentIntent. The Gale option does not create one.

Step 1: Create your custom payment method

A custom payment method type is what makes Gale appear in your Payment Element. Create one per Stripe account, in each mode.
1

Open Custom payment methods

In the Stripe Dashboard, go to Settings → Payments → Custom payment methods and click Create.
Payments settings tabs with Custom payment methods highlighted

Settings → Payments → Custom payment methods

Custom payment methods list with the Create button highlighted

Custom payment methods → Create

2

Set the name and logo

Gale is not in Stripe’s catalogue of known methods, so choose Provide a custom name and icon, then fill in:Accept both sets of terms, then click Create.
Create custom payment method panel with the custom name and icon link highlighted

Create custom payment method → Provide a custom name and icon

Create custom payment method form showing display name, logo upload, Checkout Sessions endpoint URL and the terms checkbox

Display name, logo, and the terms checkbox

3

Copy the cpmt_ id

Stripe shows the custom.type ID, beginning cpmt_. Copy it. Your frontend passes it to Stripe.js. Stripe displays it only once.
Confirmation panel showing the custom.type ID to copy

Custom payment method created — note the cpmt_ id

Step 2: Save the restricted key in Gale

Open Integrations → Gale on Stripe and paste the rk_… key. Gale uses it to write the payment record, and the page will not save unless Payment Records read and write are both granted. Paste the cpmt_… id from Step 1. Leave the signing secret blank. The Checkout Session path is the one that uses that secret. The walkthrough is on Gale on Stripe.

Step 3: Add Gale to your checkout

Two changes in your frontend, and one new endpoint on your backend. Your backend is what calls Gale, so it authenticates with your API key (glm_test_… / glm_live_…). Generate one in the Gale Merchant Dashboard under Developer Tools → API Keys — see Getting your API key. Keep it server-side; it must never reach the browser. Test and live are the key prefix. glm_test_… uses your Adyen test gateway. glm_live_… is a real charge. A test_mode field on the body is ignored.
1

Frontend — register the CPM

Stripe’s deferred Elements setup — Collect payment details before creating an Intent, Collect payment details — gains one option: customPaymentMethods, documented for the Payment Element here.
Custom payment methods render last in the Element by default. To put Gale above the card options, pass paymentMethodOrder: ['cpmt_...', 'card'] when you create the Payment Element.
2

Frontend — branch on submit

Stripe’s handler — Submit the payment to Stripe on the same deferred-Elements page — validates, mints the PaymentIntent, then confirms with stripe.confirmPayment. Gale adds a branch before the intent is created, and leaves the card path untouched.
3

Backend — create the Gale checkout

There is no separate create-cart call. This request creates the checkout and returns the hosted URL.
checkout_id looks like cs_…. That is Gale’s checkout id, not a Stripe Checkout Session.

Step 4: Set your Gale webhook URL

Gale sends the outcome to your application. In the Gale dashboard, open Developer Tools → Webhooks, add your endpoint, and subscribe to the events you fulfill on. Verify X-Gale-Signature on every delivery. Gale still sends Authorization: Bearer with the endpoint secret. That header will be removed, so use the signature as your check. See Webhooks.

Test vs live

Sandbox and live each need their own cpmt_ id. The Gale key carries the environment: glm_test_… or glm_live_….

Scope of this page

This checkout charges once. Leave mode and plan_id off the request. For a subscription, use Subscriptions. For a Stripe Checkout Session, use Stripe Checkout.

Refunds

Refund the Gale order with POST /api/v2/refunds. order_id is required. amount is optional and is in cents. Gale then sends refund.created, refund.succeeded, or refund.failed. Stripe does not send charge.refunded for this payment. Do not refund it from the Stripe Dashboard.

Failure modes

  • Wrong or missing API key, or a key from the other environment → 401/422 from /api/v2/checkout.
  • Line item missing product_id → 422. It’s required on every line item. A product_id that Gale doesn’t recognise as HSA/FSA-eligible is accepted — that item just charges on the non-eligible leg.
  • success_url / failure_url not HTTPS → checkout creation is rejected. Use a tunnel or a local certificate in development.
  • Payments are not configured for this environment → CHECKOUT_001. No checkout is created.

Test your integration

1

Use test credentials

Use your glm_test_… Gale key and your test-mode cpmt_… id. Environment is encoded in the key prefix — nothing else about the request changes.
2

Confirm the option renders

Load your checkout: Pay with FSA/HSA appears after your native methods, with the name and logo you gave the type in Stripe.If it does not, the problem is Stripe-side — wrong mode, wrong account, or a cpmt_ id that does not belong to the publishable key mounting the Element. Also check that Adaptive Pricing is not active. No Gale setting changes this.
3

Confirm the branch skips stripe.confirmPayment

Select Gale and submit. Your handler should branch before Stripe’s confirm call, so no PaymentIntent is created or confirmed — if one appears in your Stripe logs, the branch is not firing.
4

Create a checkout

Your backend endpoint calls POST /api/v2/checkout and answers { data: { checkout_url, checkout_id } }, and the shopper lands on the Gale-hosted card page.
5

Run a mixed cart

Include an item whose product_id Gale does not recognise as eligible. It should still charge, on the non-eligible leg, rather than being rejected.
6

Confirm the outcome server-side

Verify order.completed on your own backend before fulfilling. The order appears in your Gale dashboard under Orders with the reference_id you sent. Gale reports a payment record to Stripe with the restricted key from Step 2. There is no Stripe Charge.
7

Test cancel and decline

Abandon the Gale page and confirm the shopper returns to your failure_url and can pay another way, with the order left unfulfilled.
There is no PaymentIntent and no Charge for a Gale payment. So a payment_intent.succeeded or charge.succeeded handler will never fire for one. Fulfill from order.completed. The browser redirect is not something your server can verify.

Go-live checklist

  • Live Gale key (glm_live_…) on the live code path, and the live cpmt_ id in the Element
  • Restricted key saved on Gale on Stripe, with Payment Records read and write
  • Endpoint URL on the custom payment method left empty
  • product_id present on every line item
  • success_url and failure_url are HTTPS
  • order.completed verified before fulfilment, with X-Gale-Signature checked
  • One real live transaction in the Gale dashboard, and the payment record in Stripe
  • Refunds go through POST /api/v2/refunds, not the Stripe Dashboard

Create Checkout

Every field on the cart, its rule, and the response shape.

Webhooks

The signature header, the event list, and retries.

Create a refund

POST /api/v2/refunds.

Gale on Stripe

The restricted key Gale uses to report the payment back.

Subscriptions

Billing, the event for each cycle, and refunds.

Stripe Checkout

Stripe calls Gale at the custom payment method endpoint URL.