High Wire Payments

API Reference

Every public checkout method, parameter, callback, result, and error in Payment SDK 0.7.0.

This reference covers the checkout API in Payment SDK 0.7.0. HighWire is the factory, hw is the initialized instance, and checkout is the object returned by hw.mount().

For installation, server binding, and a complete checkout, use the Integration guide, Plain HTML guide, or React / Next.js guide. The separate @highwirepayments/payment-sdk/collect entry, which returns the device-session key for Direct API charges, is covered in Device screening. Coming from 0.6.0? See Upgrading from 0.6.0.

Methods at a glance

ObjectMethodReturns
FactoryHighWire.init(config)Promise<HighWireInstance>
Instancehw.mount(options)Promise<Checkout>
Instancehw.chargeSavedMethod(context)Promise<SavedMethodChargeResult>
Checkoutcheckout.submit(payer?)Promise<PaymentResult>
Checkoutcheckout.recheck()Promise<PaymentResult>
Checkoutcheckout.unmount()void

Runtime exports

After loading the pinned CDN build, read the exports from window.HighWire. The global is a namespace, rather than the factory itself.

const HighWire = window.HighWire.default;
const { HighWireError, SDK_VERSION } = window.HighWire;

default and the namespace's named HighWire export refer to the same factory. SDK_VERSION is '0.7.0'. The npm package supplies the matching declarations; use type-only imports with the CDN runtime. Examples below assume this namespace has loaded and run in an async browser function or module.

HighWire.init

HighWire.init(config: HighWireConfig): Promise<HighWireInstance>

Initialize once per checkout page. The returned Promise resolves once the device session settles, or after at most 2 seconds while it keeps loading. A screening failure never rejects it.

Parameters

config is required. It accepts these HighWireConfig fields:

FieldTypeRequiredDefaultDescription
publishableKeystringYesNoneIssued hw_pk_test_… or hw_pk_live_… key, with 32 URL-safe characters after the prefix.
apiBasestringYesNoneHighWire gateway origin. HTTPS is required except for localhost development.
fieldsOriginstringNoapiBaseOrigin serving the card field and drop-in. Set only when supplied by HighWire.

URLs are normalized to their origins. Use the matching key and gateway from onboarding. Register the checkout's origins; see Security & server verification.

Returns and errors

Returns a frozen HighWireInstance with readonly mount and chargeSavedMethod methods. It has no riskSessionKey() method; see Device screening. Invalid fields in a provided configuration object throw HighWireError with HW_UNSUPPORTED synchronously, before a Promise is returned. Omitting the required object or passing null instead causes a plain synchronous TypeError. Put the call itself inside try when handling errors.

hw.mount

hw.mount(options: MountOptions): Promise<Checkout>

Create or reuse the order's payment and draw the configured checkout at the payment step. One checkout may be mounted at a time per instance. The HighWire session chooses the layout; see Drop-in & wallets.

Parameters

options is required. Every MountOptions field is listed below:

FieldTypeRequiredDefaultDescription
containerstring | ElementYesNoneCSS selector resolving to an existing element, or the DOM element itself.
amountnumberYesNonePositive integer cents. 2999 represents USD 29.99.
currencystringYesNoneOnly USD is supported; use 'usd'.
savePaymentMethodForFutureUsebooleanNofalseShow the shopper an unticked save-card box, in the card field or under a drop-in form that uses your Pay button. Only the shopper's tick saves the card, under the email submit() sends. A drop-in form with its own button, Apple Pay, and Google Pay save no card.
billingAddressForm'none' | 'full'No'none'Who collects the billing address for a drop-in form that uses your Pay button. 'none': your page passes the full address to submit(). 'full': the form shows its own billing fields; see billing fields in the form. Other checkouts reject 'full' with HW_UNSUPPORTED.
onReady() => voidNoNot registeredCard field or drop-in ready.
onAvailabilityChange(available: boolean) => voidNoNot registeredA drop-in form that uses your Pay button can, or can no longer, take a submission.
onChange(card: CardState) => voidNoNot registeredCard completeness and validation state changed.
onProcessing(method: PaymentMethod) => voidNoNot registeredPayment confirmation began.
onResult(result: PaymentResult) => voidNoNot registeredResult from any payment method.
onError(error: HighWireError) => voidNoNot registeredOperation or form-loading failure.

See Callbacks for their complete payloads. Checkout idempotency keys are generated by the SDK; mount() accepts no shopper email, merchant key, merchant order ID, or individual payment-method selection. Pass the email to submit(). In plain JavaScript a customerEmail passed to mount() is ignored; TypeScript rejects it.

Returns and errors

Resolves with a Checkout once its parts are mounted. Form readiness and loading errors are reported separately through callbacks, so a resolved mount does not guarantee a usable card field.

Checkout memberTypeMeaning
paymentIdreadonly stringPayment charged by this checkout. Bind it to the order on your server before enabling any payment controls.
requiresSubmitreadonly booleantrue for layouts with a card field and for a drop-in form that uses your Pay button; show your Pay button. When false, the drop-in has its own button.
submit(payer?: PayerDetails) => Promise<PaymentResult>Submit the card field or the drop-in form; see checkout.submit().
recheck() => Promise<PaymentResult>Check an unresolved drop-in payment again; see checkout.recheck().
unmount() => voidRemove checkout UI; see checkout.unmount().

Rejections include invalid options (HW_UNSUPPORTED), a refused payment (HW_DECLINED), authorization/transport failures, and attempts to mount while another payment is unresolved. The same rejection reaches onError when provided; show it once. See the error codes.

billingAddressForm: 'full' on any other checkout rejects HW_UNSUPPORTED after the payment is created; mount again with 'none' to reuse that payment.

Keep the container non-interactive until your backend has verified and bound the payment. On the same instance, an open payment is reused for the same amount, currency, and savePaymentMethodForFutureUse. The email plays no part, so two orders with the same amount reuse one payment, even after unmount(). For another order with the same options, use a fresh instance once your backend authorizes it. Another amount creates another payment; another save option creates one once the last payment can no longer capture. While an unresolved payment of a drop-in form that uses your Pay button may still capture, another amount or save option rejects HW_TOKENIZE_IN_PROGRESS. See normalization and remounting.

checkout.submit

checkout.submit(payer?: PayerDetails): Promise<PaymentResult>

Pay with the mounted card field, or with a drop-in form that uses your Pay button. Call only when requiresSubmit is true, the form can take a payment (onChange reports complete, or onAvailabilityChange reports true), and no operation is running. Wallets and drop-in forms with their own button use their own controls.

Parameters

payer carries the shopper's email, so it is required for a card payment. A drop-in form that uses your Pay button can omit it only after one of its attempts on this payment was declined, and only when it collects the billing address itself. Its PayerDetails fields are:

FieldTypeRequiredDefaultDescription
customerEmailstringConditionalNoneThe shopper's email; a saved card is filed under it. Required for a card payment: missing or malformed, submit() rejects HW_INCOMPLETE before anything is sent. A drop-in form that uses your Pay button falls back to the email of its last declined attempt on this payment; see email on a drop-in form.
customerPhonestringNoOmittedShopper's phone number. Sent with a card payment only.
billingAddressBillingAddressConditionalOmittedBilling details, using the fields below. A drop-in form that uses your Pay button needs the full address, with at least name, country, and postalCode, unless mounted with billingAddressForm: 'full', which rejects any billingAddress.

Every BillingAddress field is an optional string, omitted by default:

FieldDescription
nameBilling recipient. Separate from the cardholder name entered in the card field.
countryTwo-letter country code, such as 'US'.
line1Street address.
line2Apartment, suite, or unit.
cityCity.
stateState or region.
postalCodePostal or ZIP code. Pass a string so leading zeros are kept.

Email, phone, and billing strings are trimmed; blank values are omitted. Amount, currency, and the save option are fixed at mount, and the shopper's tick is read at submit; submit takes no card values or merchant idempotency key.

A card payment sends line1, city, state, and postalCode, and ignores name, country, and line2. A drop-in form that uses your Pay button sends every address field, uppercases country, and copies the details when called, so later changes to the object do not affect that attempt. It rejects a non-string field, a malformed email, or a country that is not two letters with recovery correct, before anything is sent. The SDK checks name and country; the form validates the rest of the address for the selected country and refuses one without a postal code.

Email on a drop-in form that uses your Pay button

HighWire screens and binds the email before the form's processor can charge the card:

  • An omitted email falls back to the email of the payment's last declined attempt. Before any decline, submit() rejects HW_INCOMPLETE.
  • A corrected email is screened again. One payment takes up to 3 different emails; past that, submit() rejects HW_INCOMPLETE with recovery correct, as it does for an email HighWire refuses. Submit again with the last email the payment accepted.
  • A screening denial rejects HW_DECLINED with recovery recheck.
  • A changed email or save box while the payment is live rejects HW_TOKENIZE_IN_PROGRESS with recovery recheck.

After either recheck rejection the payment is kept: a later submit() only reads it, and this checkout takes no other payment.

Returns and errors

Returns the same PaymentResult delivered to onResult. A decline resolves; operational failures reject. Handle the result once. Required 3-D Secure verification opens within this call; keep checkout mounted during it.

A drop-in form that uses your Pay button resolves succeeded, pending, or declined. A card decline resolves declined and calls onResult: with retryable: true the shopper can use another card and submit again; with retryable: false the checkout has ended. When the form refuses the payment details, billing address, or email, submit() rejects HW_INCOMPLETE with recovery correct, and the shopper can correct them and submit again. Its errors carry recovery.

const result = await checkout.submit({
  customerEmail: 'shopper@example.com',
  customerPhone: '+14155550123',
  billingAddress: {
    name: 'Alex Shopper',
    country: 'US',
    line1: '123 Example Street',
    line2: 'Suite 400',
    city: 'San Francisco',
    state: 'CA',
    postalCode: '94105',
  },
});

For a lost answer, retry the same checkout's submit to retain the attempt. A card retry resends the first attempt's email and billing details; edits the shopper made in between are not sent. On a drop-in form that uses your Pay button, a submit after an unknown outcome, a screening denial, or a refused email or save-box change only checks the original payment, for up to 3 minutes; it never sends it again. After unmount, a new submit only rejects, so keep a rejection handler even with onError. See Errors and retry guidance.

checkout.recheck

checkout.recheck(): Promise<PaymentResult>

Parameters: none. Read the payment of a drop-in form that uses your Pay button once more, after an error with recovery recheck or a pending result. It never creates a payment or submits again, and it works after unmount().

Resolves succeeded when the gateway reports the payment succeeded, which ends the checkout, and pending otherwise. A succeeded result carries customerId and paymentMethodId when the shopper saved the card. It does not call onResult: show its result yourself. A pending answer does not permit another payment; check the order on your server first.

Rejections also reach onError until unmount(), and after it only while a submit() is still running. Otherwise only the returned promise rejects, so keep a catch on it:

CaseRejection
submit() is still runningHW_TOKENIZE_IN_PROGRESS with recovery wait. Call again once it settles.
The payment could not be readThe read's code, such as HW_NETWORK, with recovery recheck.
No submission left to checkHW_NOT_READY with recovery unavailable.
Any other checkoutHW_UNSUPPORTED.

checkout.unmount

checkout.unmount(): void

Parameters: none. Returns: undefined (void). Remove the checkout's slots and processing state, and restore the container's previous layout attribute. Use during page/component cleanup.

Unmounting does not cancel a charge; an active payment may still call a callback. An unanswered card confirmation rejects HW_DESTROYED. A submission of a drop-in form that uses your Pay button whose outcome is unknown, or that was rejected with recovery recheck, survives unmount and blocks another order on the instance; follow cleanup and recovery. This method returns synchronously without a documented HighWireError rejection.

hw.chargeSavedMethod

hw.chargeSavedMethod(context: SavedMethodChargeContext): Promise<SavedMethodChargeResult>

Charge a card the shopper saved on an earlier checkout. No mounted form is required, and the call can be made after a page reload using the saved identifier and your stored charge key.

Parameters

context is required. Every SavedMethodChargeContext field is required and has no default:

FieldTypeDescription
paymentMethodIdstringNon-empty saved identifier returned by the original card's PaymentResult.
amountnumberPositive integer cents, no higher than the payment that saved the card.
idempotencyKeystringNon-empty stable key for this add-on charge, stored by your backend and reused on retries and reloads.

This is the only checkout SDK method that accepts a merchant idempotency key. Reuse is subject to account limits.

Returns and errors

Returns SavedMethodChargeResult with these fields:

FieldTypeAvailability
status'succeeded' | 'declined' | 'pending'Always. A decline resolves.
paymentIdstringAlways; the new payment, including a declined one.
amountnumberAlways; charged/requested amount in cents.
paymentMethodIdstringAlways; saved method used.
const addOn = await hw.chargeSavedMethod({
  paymentMethodId: 'SAVED_PAYMENT_METHOD_ID',
  amount: 500,
  idempotencyKey: 'STABLE_KEY_STORED_WITH_THIS_ADD_ON',
});

A card saved through a drop-in form that uses your Pay button is collected asynchronously: expect pending and settle it from your server. If its issuer asks for 3-D Secure again, the charge does not capture, because this call has no shopper verification step.

Verify every result on your backend. One saved-method call can run per instance; another rejects HW_TOKENIZE_IN_PROGRESS. Validation can reject HW_INCOMPLETE or HW_UNSUPPORTED; changing the amount under an existing key can also reject HW_UNSUPPORTED. Retain the original key for an unknown outcome. See saved-card errors and key recovery rules before starting a new charge.

Callbacks

All callbacks are optional properties of MountOptions; omitting one installs no handler. Their return values are ignored. Card values are never part of a callback payload.

CallbackPayload and behavior
onReady()No payload. Card field or drop-in ready; card completeness is reported separately. Called once.
onAvailabilityChange(available)boolean. Only for a drop-in form that uses your Pay button: false while the form loads, true once it can take a submission, and false again while it reloads and when the checkout ends. Enable Pay only while true. It does not say the details are valid, or that another payment is allowed.
onChange(card)CardState. A reload that clears the card reports empty state.
onProcessing(method)PaymentMethod. Disable your Pay button while confirming.
onResult(result)PaymentResult from card, Apple Pay, Google Pay, or drop-in.
onError(error)HighWireError. Mount/submit/recheck reject with this same error. Form-load errors can be reported without a mount rejection. Errors from a drop-in form that uses your Pay button carry recovery.

Active payments may call callbacks after unmount. An unanswered card confirm reports HW_DESTROYED through onError and submit rejection. Show each error once.

CardState

FieldTypeMeaning
completebooleanCard ready to submit. Also check your busy/closed state before enabling Pay.
emptybooleanCard field is empty.
brandstring | nullDetected card brand, or null when unknown.
error{ code: string } | nullField validation error, or null. No card values.

PaymentMethod

'card' | 'applePay' | 'googlePay' | 'dropIn'

These are the values passed to onProcessing, and the container's data-hw-processing attribute while a payment is being confirmed. A drop-in form that uses your Pay button reports 'dropIn' when submit() sends a new submission, not when it only checks an earlier one.

PaymentResult

FieldTypeAvailability and meaning
status'succeeded' | 'declined' | 'pending'Always. See status handling below.
paymentIdstringAlways; the same payment as checkout.paymentId.
retryablebooleanPresent on every decline; absent for other statuses.
paymentMethodIdstringOptional; saved card identifier, only when the shopper ticked the save box and the card was saved. On a drop-in form that uses your Pay button, only on succeeded. A card saved before keeps its identifier.
customerIdstringOptional; always returned together with paymentMethodId.
maskedCardstringOptional; first 6 and last 4 digits when available. Never on a result from a drop-in form that uses your Pay button.

A reopened 3-D Secure challenge can omit paymentMethodId, customerId, and maskedCard. There is no decline-reason field.

StatusCheckout state and action
succeededCheckout ended. Show confirmation; fulfill only after your server verifies the bound payment's captured status, amount, and currency.
declined, retryable: trueCheckout remains open; try another card or method on the same payment. Also applies to a drop-in form that uses your Pay button. A card the gateway's velocity checks refuse resolves this way too, without charging; the same card at the same amount is refused again for 5 minutes.
declined, retryable: falseCheckout ended; reconcile before authorizing another payment.
pendingCheckout ended but payment unresolved; read it on your server before taking another payment.

Fulfillment requires server verification.

HighWireError

HighWireError extends Error and is exported by the CDN namespace. SDK failures expose:

PropertyTypeMeaning
codereadonly HighWireErrorCodeMachine-readable code listed below. Use for recovery and your own customer-facing copy.
recoveryreadonly CheckoutRecovery | undefinedWhat the shopper can do next. Present on errors from a drop-in form that uses your Pay button, absent otherwise. See CheckoutRecovery.
messagestringDiagnostic message inherited from Error; avoid displaying it directly to shoppers.
namestring'HighWireError'.

The exported constructor is new HighWireError(code: HighWireErrorCode, message: string, recovery?: CheckoutRecovery). code and message are required and have no default. SDK failures already provide instances; integrations normally inspect rather than construct them.

try {
  await checkout.submit({ customerEmail: 'shopper@example.com' });
} catch (error) {
  if (error instanceof HighWireError) console.error(error.code, error.recovery);
}

CheckoutRecovery

'correct' | 'retry' | 'wait' | 'recheck' | 'unavailable'

Exported as a type. When an error carries recovery, act on it before its code:

RecoveryMeaning and action
correctThe payer details, or the card or billing fields in the form, were refused. This includes an email HighWire refuses, and a fourth different email on one payment. Let the shopper correct them, then submit again.
retryThe payment was not sent. Allow another submit() while onAvailabilityChange reports true.
waitAnother operation is still running. Keep Pay disabled; its result or error follows. The data-hw-processing attribute stays in place.
recheckThe payment may still capture: its outcome is unknown, HighWire's screening denied the shopper's email (HW_DECLINED), or a changed email or save box was refused while it was live (HW_TOKENIZE_IN_PROGRESS). Keep Pay disabled and tell the shopper it is being confirmed. Check it on your server, or call checkout.recheck() once the running submit() settles. Can arrive through onError while submit() still runs.
unavailableThis checkout cannot take a payment. Stop its controls and check the order on your server.

A pending result or a recheck error does not permit another payment. Check the original payment on your server before starting another checkout, even if a later status read shows it declined or expired.

Error codes

The codes below cover the exported HighWireErrorCode union in 0.7.0. Recovery depends on which method failed; a transport error during mount is different from a lost submit answer. When an error carries recovery, follow it before the code.

Configuration and input

CodeMeaning and action
HW_UNSUPPORTEDInvalid config/options, unsupported checkout, second mount, or submit on a checkout whose requiresSubmit is false. Also billingAddressForm: 'full' on another checkout or with a billingAddress, and recheck() on another checkout. On a drop-in form that uses your Pay button, also a payer or payer field of the wrong type, with recovery correct. A refused card attempt can also report this without charging, leaving checkout open.
HW_UNAUTHORIZEDKey/origin refused. Check onboarding configuration. Some unreadable key/account refusals appear as HW_NETWORK because of CORS.
HW_INCOMPLETEIncomplete card, missing/malformed email on submit(), missing billing name or country for a drop-in form that uses your Pay button, details that form refused, or missing saved-method identifier/key. On that form, also an email HighWire refuses, more than 3 different emails on one payment, or a submission HighWire did not take. Fix input before retrying. That form not being ready yet rejects it with recovery retry.
HW_NOT_READYCard field not loaded or reloading. Wait for a complete onChange. Also recheck() with no submission to check, with recovery unavailable.
HW_DECLINEDPayment creation refused. Nothing mounted or charged; show decline copy without looping retries. On a drop-in form that uses your Pay button, submit() also rejects it with recovery recheck when HighWire's screening denies the shopper's email: the payment is kept, and the checkout takes no other payment.

Transport and throttling

CodeMeaning and action
HW_NETWORKNetwork/CORS failure. From submit, retry the same checkout; from mount, retry mount. Persistent mount failures also require checking the key/account.
HW_TIMEOUTRequest, form loading, or 3-D Secure timed out. Retry a rejected mount; retry the same submit after a lost answer. An asynchronous form timeout requires unmount/remount.
HW_SERVICE_UNAVAILABLEGateway could not answer. Retain the attempt on submit retries; a rejected mount leaves nothing mounted.
HW_RATE_LIMITEDReadable rate/velocity refusal from mount(), a status read, submit() on a drop-in form that uses your Pay button (recovery retry), or chargeSavedMethod(). Back off before retrying. A card submit refused by velocity checks resolves declined with retryable: true instead. For a saved-card velocity refusal retained under its key, reconcile before a later charge with a new key.

Form and operation state

CodeMeaning and action
HW_TOKENIZE_IN_PROGRESSAnother operation is running or an earlier payment is unresolved. Wait or recover the same attempt; do not bypass it with a new instance until your server has reconciled the earlier payment. With recovery wait, keep Pay disabled until the running operation settles. On a drop-in form that uses your Pay button, also a refused email or save-box change while its payment is live (recovery recheck), and mount() with another amount or save option while that payment may still capture.
HW_DESTROYEDCheckout unmounted. If card confirmation was sent, it may have charged; remount identical options on the same instance and resubmit.
HW_PROTOCOL_MISMATCHForm/SDK protocol incompatibility, reported through onError. Unmount/remount; contact HighWire if persistent.
HW_IFRAME_UNRECOVERABLEForm cannot recover, reported through onError. Unmount/remount the same order.
HW_TOKEN_EXPIREDIncluded in the public code union, but has no separately documented checkout recovery contract in 0.7.0. Reconcile payment and contact HighWire if received.

Ended checkouts

CodeMeaning and action
HW_SESSION_EXPIREDPayment session/check-out ended, or its outcome was not observed. Read payment on your server before offering another attempt; it may have captured. On a drop-in form that uses your Pay button, when the form reports its session expired, submit() reads the payment and resolves succeeded instead if it was paid.
HW_3DS_ABANDONEDVerification dialog closed. Checkout ended, but payment can still capture. Reconcile before remounting.

Reconcile pending, abandoned, or unknown outcomes before remounting. Your backend authorizes another payment; SDK remount permission does not prove that the previous attempt failed.

Saved-card reuse

CodeMeaning and action
HW_UPSELL_NOT_READYOriginal payment not settled. Retry shortly with the same add-on key.
HW_UPSELL_AMOUNT_EXCEEDEDAmount above the permitted original-payment bound. Reconcile the refusal; a lower amount is a new charge and requires a new key.
HW_UPSELL_REFUSEDSaved card cannot be charged again. Do not retry it in a loop.

See the integration retry guide for payment recovery, and safe diagnostics for support.

On this page