Tapaya

Customer Details & Shipping

Collect customer details and approve fixed or dynamic delivery totals for cards, Apple Pay, and Google Pay.

Apple Pay
Apple Pay sheet showing the total, the card, a shipping address, a shipping method, and a billing address
Google Pay
Google Pay sheet showing the card, a shipping address, the total, and a Pay button

Collect contact details and a delivery address at checkout, offer delivery options, and charge only a total your server approved. The same settings apply to the card form, Apple Pay, and Google Pay, in both Hosted and Embedded Checkout.

What the wallet sheet collects

Apple Pay and Google Pay do not use your form. They open their own payment sheet, ask for the details you request, and return them to you.

In the sheetYou request it withYou read it from
Delivery addressshippingOptionscustomer.shippingAddress
Delivery methodshippingOptions options or approved quotesshippingQuote
Email, name, phonecustomerCollectioncustomer, and walletContact for receipts
Billing addresscustomerCollection.billingAddresscustomer
TotalYour server approves itThe payment, read on your server

If the total changes, the shopper authorizes again in the sheet, and an expired quote is refused before charging.

Where Apple Pay and Google Pay differ

Apple PayGoogle Pay
Before it appearsEmbedded Checkout needs an active shop domain. Cross-origin Apple Pay needs Safari 17 or later.Live payments need a configured Google Pay merchant ID.
DeliveryNeeds supported native shipping callbacks. Otherwise card entry remains available.Native shipping callbacks.
TestingReal supported devices only.Real supported devices. A simulated TEST sheet does not verify production behavior.

A wallet button also depends on the shopper's device and browser, so enabling a wallet does not guarantee it appears everywhere. See Checkout settings. For design rules, see Apple's Apple Pay guidelines and Google's Google Pay brand guidelines.

Implementation

Collect contact and billing details

Set the fields to collect when creating a hosted session or embedded payment:

customerCollection: {
	email: 'required',
	name: 'optional',
	phone: 'optional',
	billingAddress: 'none',
}
  • Each field accepts none, optional, or required.
  • An omitted policy or null uses merchant defaults. An explicit object sets omitted fields to none, and {} disables collection.
  • Prefill values through customer.email, name, phone, billingAddress, and shippingAddress.

Read accepted details from customer on session or payment status reads. These are shopper-supplied details, not verified identity.

Wallets

For a wallet opened before preparation completes, pass the matching wallets.customerCollection hint, so the sheet asks for the same fields. The server policy stays authoritative.

Wallet results can expose walletContact: { method, customer } with email, name, phone, and billing address for receipt presentation. This browser snapshot does not prove payment or replace the order's server-approved delivery address.

Offer fixed delivery options

Pass shippingOptions when creating the payment or hosted session:

shippingOptions: {
	dynamic: false,
	options: [{
		id: 'standard',
		label: 'Standard delivery',
		price: 300,
		amount: 1500,
		tax: 200,
		countries: ['CZ', 'SK'],
	}],
}
FieldMeaning
amountThe complete final charge, including the delivery price and tax. Checkout does not add them again.
price, taxInteger minor units. tax: null or omitted means unspecified VAT; 0 means no VAT.
countriesUppercase two-letter country codes. An empty list permits any country.

The form and the wallet sheets collect a delivery address and offer the matching options. Without shippingOptions, the creation amount stays fixed.

If a quote changes the displayed total during submission, card checkout asks the shopper to review the new amount and select Pay again. Read the selected option and revision through shippingQuote.

Approve dynamic delivery

When delivery depends on the address, set dynamic: true and approve each quote revision from your server. Embedded Checkout asks through browser handlers; Hosted Checkout calls your server directly.

Create the payment with shippingOptions: { dynamic: true }. Configure both change handlers to ask your backend for approval. Like wallets.customerCollection, wallets.shippingRequired is a hint for wallet sheets opened before preparation completes:

import type { ShippingChangeEvent } from '@tapayadot/checkout/client'

const approveDelivery = async (event: ShippingChangeEvent) => {
	const response = await fetch('/api/delivery', {
		method: 'POST',
		headers: { 'content-type': 'application/json' },
		body: JSON.stringify(event),
	})
	if (!response.ok) throw new Error('Delivery could not be approved.')
}

const payment = browserTapaya.createPayment({
	clientSecret,
	wallets: { amount: 1200, currency: 'EUR', shippingRequired: true },
	onShippingAddressChange: approveDelivery,
	onShippingOptionChange: approveDelivery,
	onShippingQuoteChange: ({ amount, currency }) => updateOrderTotal(amount, currency),
})

Events contain paymentId, revision, address, and selectedOptionId. Your backend authenticates the shopper, checks access to the order, and reads the current pending quote. Calculate the options from your stored cart and delivery rules, then approve that revision:

await tapaya.checkout.sessions.approveShippingQuote(paymentId, {
	revision,
	options,
	selectedOptionId,
	expiresAt: Math.floor(Date.now() / 1000) + 300,
})

expiresAt is Unix time in seconds. To reject delivery, approve with no options and error: 'unsupported_destination' or 'quote_error'.

Browser handler return values cannot set the charge total. After a handler resolves, the frame reads the server-approved quote and rejects stale revisions, expired quotes, and unapproved totals. Protect your approval route with the same authentication and CSRF controls as payment preparation.

Use onShippingQuoteChange or snapshot.shippingQuote to update the order summary and Pay label. Notifications include the revision and totals without the delivery address or a wallet token. The React hook supports the same callbacks without remounting when callback functions change.

Verify the accepted total

Read the payment on your server and compare its order reference, currency, and amount with the final total your backend approved. Persist that total with the accepted quote revision. Comparing only with the initial subtotal rejects legitimate delivery changes.

checkout.sessions.prepare() validates the original creation input through replay when a delivery quote changes the read amount. Your fulfillment check still uses the accepted final total. The accepted address is in customer.shippingAddress, and the selected delivery option is in shippingQuote.

Test wallets on real devices

Wallet shipping uses native address and option callbacks. A changed total needs another authorization, and an expired quote is refused before charging. Apple Pay shipping requires supported native shipping callbacks; if they are unavailable, card entry remains available.

Test shipping, contact collection, and cancellation in both wallets on real supported devices before enabling delivery in production. The go-live checklist lists the checks.

Чогось бракує на цій сторінці?Надішліть запит на функцію. Ми додамо цю сторінку, щоб команда бачила контекст.