Repository navigation
Releases: whopio/elements
Release list
1.9.0
Minor Changes
-
The wallet send completion event supports bill-pay recipients identified by their saved payout method, with
kind: 'bill_pay', without requiring a Whop user. -
The
paymentelement'schangepayload now carriespaymentMethod, the selected payment method, saved or new, ornullwhile nothing is selected: a saved method'sid, itstypeandcategory, thedisplayNameandiconsthe element shows for the pick (withbalance.imageUrl, a balance owner's image), a card'snetwork,last4andfunding, whether it needs a billing phone (requiresBillingPhone), and thecountriesit can pay from in the charge's currency. The top-leveltype,requiresBillingPhoneandmethodare deprecated in its favor, and the top-levelsupportsBuyerFeeis deprecated with no replacement: Whop prices its buyer service fee itself. ThecardFieldschangepayload reports the detectednetworkand the number'slast4. -
The verifications
capabilitieselement takeshidePayouts,hideBankDeposits,hideCardsandhideAdsto drop individual capability rows. -
New
paymentRequestoptionpaymentMethodConfigurationnarrows the walletscanMakePayment()reports, in the API'senabled,disabled, andinclude_platform_defaultsformat. -
A payment request now lets you approve or refuse a payment before its confirmation token is created. With an
onPaymentAuthorizationhandler, the sheet waits once the buyer authorizes, and the event carries the payer, the payment method, the shipping address and option, and the total. AnswerrespondWith({ approved: true })to create the token, orrespondWith({ approved: false, message })to refuse. A refused payment gets no token: Apple Pay and Google Pay show your message so the buyer can change something and pay again, and on PayPalshow()rejects withpayment_request_refused. A handler that throws or does not answer within 25 seconds refuses the payment, in time for Apple Pay and Google Pay to show the refusal. Without a handler, every sheet works as before. -
contentSecurityPolicy()now includes the Plaid hosts the payment and checkout elements need when they link a bank account on your page. Pass{ bankConnections: false }to it on pages that don't take bank account payments. -
A payment request now fires
onPaymentMethodChangewhen the buyer selects a card in Apple Pay, and when the Google Pay sheet opens and each time the buyer switches cards there, right after that card'sonBillingAddressChange. The event carries the method type, what the wallet tells about the card before authorization (Apple Pay reports its funding and usually withholds the network; Google Pay reports the network) and its redacted billing address. Answer it like the other change events:updateWith({ amount, lineItems })reprices the sheet,updateWith({})keeps the total, andupdateWith({ errors })refuses the card until the buyer picks another. The sheet updates once both events are answered, and a card either event refuses leaves the totals as they were, whatever the other answer priced. -
On phones, the address element no longer shows street suggestions under the street field, where the keyboard covered them. A search button at the end of the street field opens a full-screen address search instead: its search field starts with what the buyer already typed, Google's suggestions are listed under it, and picking one fills the whole form. With
autocomplete: falsethe button does not appear. Larger screens keep the list under the field.Postal codes that are only digits now open the number pad, and on touch screens the address inputs set their text at 16px so iOS no longer zooms the page when one is focused. The compact layout's bordered group can be styled with the new
.whop-AddressGroupclass, and the phone's search button with.whop-AddressSearchButton. -
paymentRequestaddresses carryname, the name on the address, the same field the address element and the API use.recipientstill carries the same value and is deprecated: usename. -
paymentRequest'sshow()result and itsconfirmationTokenevent carrybilling, the full billing address the confirmation token carries, ornullwhen the wallet gave none. Apple Pay and Google Pay give the card's billing address; on PayPal it is the address the buyer picked in PayPal, the one its total was taxed on. -
Wallet withdrawals can offer a better payout method with estimated savings. Review its fee and arrival estimate, then connect it before switching. Host-managed withdrawals can supply the offer through
payoutQuote.recommendedMethod. -
The
adsnamespace has a newads-agreementelement for signing the Whop Ads agreement. Mount it inline or open it as a modal to let an account sign before its first launch; it emitssignedwith the version that was signed.campaign-creatornow opens it over the builder when a launch needs a signature, and resumes the launch once it is signed. -
element "addressSearch" added (
payments.addressSearch) -
resource option "paymentMethodConfiguration" added (
payments.paymentRequest.options.paymentMethodConfiguration) -
resource event "paymentMethodChange" added (
payments.paymentRequest.events.paymentMethodChange) -
resource event "paymentAuthorization" added (
payments.paymentRequest.events.paymentAuthorization) -
resource event failure answer "paymentAuthorization" added (
payments.paymentRequest.replyFail.paymentAuthorization) -
resource event failure answer "paymentMethodChange" added (
payments.paymentRequest.replyFail.paymentMethodChange) -
prop "hidePayouts" added (
verifications.capabilities.props.hidePayouts) -
prop "hideBankDeposits" added (
verifications.capabilities.props.hideBankDeposits) -
prop "hideCards" added (
verifications.capabilities.props.hideCards) -
prop "hideAds" added (
verifications.capabilities.props.hideAds) -
element "addressSearch" added (
checkout.addressSearch) -
element "ads-agreement" added (
ads.ads-agreement) -
page-requirement group "bankConnections" added (connect:https://production.plaid.com, connect:https://sandbox.plaid.com, frame:https://cdn.plaid.com, script:https://cdn.plaid.com) (
_pageRequirements.bankConnections)
Patch Changes
- Show ad affiliate payouts in the default wallet activity feed and the Ads activity type filter.
- The address country list no longer offers Abkhazia, which showed as a bare "AB", or the Netherlands Antilles, which showed as a second Curaçao.
- The email element no longer shows a label bar in its loading placeholder when it is mounted with
label: false, so the placeholder matches the field that replaces it. - Payment request shipping answers now behave the same way on Apple Pay and Google Pay. When an answer's
shippingOptionsdrops the selected option, the first option becomes the selection without anonShippingOptionChange, and an emptyshippingOptionslist changes nothing. The result'sshipping.optionis the option the sheet showed, the first offered one when the buyer never picked another. On Apple Pay and Google Pay, a shipping handler that hasn't answered within 25 seconds fails that address or option in the sheet, instead of the wallet failing the payment, and its later answer is ignored. An address answer with an error, or one that failed this way, now keeps Pay refused until a later address is answered cleanly. On Apple Pay, a shipping option answer that replaces the options now updates the sheet's options, and a cancelled or failed attempt no longer carries the totals, line items or options its answers wrote into the next sheet.show()trims spaces around a passed email before it uses it. - The card fields' loading placeholder is easier to see in light mode: its bars use a stronger gray, so they no longer fade into the page while the secure inputs load.
- Partner payments in the activity list show a percentage icon instead of an empty circle.
- PayPal express now saves the buyer's PayPal account with the purchase, the way Apple Pay and Google Pay save the card they pay with. Unlike those two sheets, PayPal also asks the buyer to agree to future payments inside its own window. Express checkout offers PayPal on renewing plans and free trials too, and a seller can charge the saved account later with the buyer away, through renewals or a native
POST /paymentswith itspayment_method_id(Api-Version-Date2026-09-02-1 or later), such as a one-click upsell. On the payment request,canMakePayment()now reportspayPalfor a request withsetupFutureUsage, and anoff_sessionrequest may be $0, which saves PayPal without a charge. The token carries the request'ssetupFutureUsagelike the other wallets' tokens. A saved PayPal account charges only with the buyer away, like a saved Apple Pay or Google Pay card. - On PayPal, a payment request's shipping address or shipping option handler that hasn't answered within 25 seconds now refuses that address or option inside PayPal, as it does on Apple Pay and Google Pay, and its later answer is ignored. Before, the ask waited until PayPal gave up on it.
- Payout timelines show bank-specific descriptions only for bank deposits.
- In a withdrawal, a PayPal payout method that PayPal refused now tells the seller how to fix it: add PayPal again with their PayPal email, or a phone number that starts with + and the country code.
1.8.0
Minor Changes
- 2a5a62e: The payment element and the express checkout element take the same
walletsobject: setapplePay,googlePay, orpayPalto'never'and that element stops offering the wallet, and every key defaults to'auto', which keeps today's behavior. A page that draws its own Apple Pay, Google Pay, or PayPal buttons withpaymentRequestcan now passwalletsto the payment element so buyers see each wallet once (payPal: 'never'removes the PayPal method). The express checkout element's array form (wallets={['apple_pay', 'google_pay']}) still works, but it is deprecated and will be removed in the next major version; the types and docs mark it. (#33920) - 2a5a62e: A payment request's
onPromoCodeChangeanswer can now carryshippingOptions, so a free-shipping code can change the shipping rates in the Apple Pay and Google Pay sheets while they stay open. The buyer's selected option stays selected while itsidis still in the list. (#33920) - prop "wallets" added (
payments.payment.props.wallets) - element "address" no longer waits for required element "branding" (
payments.address.exempt.branding) - element "email" no longer waits for required element "branding" (
payments.email.exempt.branding) - element "taxId" no longer waits for required element "branding" (
payments.taxId.exempt.branding) - the array member of prop "wallets" deprecated (
checkout.expressCheckout.props.wallets.deprecated.array) - element "branding" became required — existing consumers must now mount it (
payments.branding.required) — breaking, shipped without a major: the 1.0.0 docs already required the branding element; an earlier change loosened the runtime check by mistake
Patch Changes
-
2a5a62e: The branding element is required on every payment form again: the other payments elements stay in their loading state until it is mounted, and
createConfirmationTokenrefuses withBRANDING_NOT_MOUNTEDwithout it.breaking-without-major:
payments.branding— the 1.0.0 docs already required the branding element; an earlier change loosened the runtime check by mistake (#33920)
1.7.0
Minor Changes
- edad277: A payment request's
onPromoCodeChangeanswer can now carrylineItemsbesideamount, so the Apple Pay and Google Pay sheets show the discount line and the tax it changes while they stay open. Before, a promo answer repriced only the total, and the sheet kept the line items it opened with. (#33806)
Patch Changes
- edad277: In the payment element's
separatedlayout, the "More saved payment methods" and "N more payment methods" rows now carrywhop-PaymentMethodSeparatedlike the methods around them, soappearance.classesstyling for separated cards reaches them too. Before, they kept the default card surface and could not be restyled. (#33806)
1.6.0
Minor Changes
- 39455b8: The
addresselement takesexpanded: trueto show every address field from the start, instead of opening with the street address and revealing the rest after the buyer picks a suggestion or enters it manually.falsestays the default. (#33799) - 39455b8: The selected payment method's item now carries
whop-PaymentMethodSelected, soappearance.classescan style the whole selected method, its row and its expanded fields together. Before, only the row (whop-PaymentMethodRowSelected) and its radio were marked. (#33799) - 39455b8: The
addresselement takeslayout: "wrap". It keeps thefulllayout's separate, labeled fields and also puts city, state and postal code side by side. Those and the pairsfullalready sets side by side (first and last name, organization) fit as many to a row as the element's width allows and wrap as it narrows.fullstays the default. (#33799) - prop "expanded" added (
payments.address.props.expanded)
Patch Changes
- 39455b8: When an Apple Pay or Google Pay sheet on a checkout can't recalculate the total for the buyer's card, the sheet now asks for another card instead of keeping the previous total. When the payment is priced in a different currency than the attached checkout session charges in, the wallet sheet doesn't open, and the confirm rejects with a
SESSION_CURRENCY_MISMATCHerror. (#33799) - 39455b8: Elements and providers that React mounts, unmounts and mounts again now come back working. Under React StrictMode in development, an element added after the page loaded, such as a billing
<AddressElement>shown when a "same as shipping" box is unticked, used to render an empty box, and inside a React 19<Activity>an element or provider that was hidden and shown again stayed blank. They now load a fresh element instead. (#33799)
1.5.0
Minor Changes
- a6450aa:
paymentRequestsheets can offer a promo code field: setrequestPromoCode, prefill a code withappliedPromoCodeandappliedPromoDescription, and answeronPromoCodeChange: any answer without anerrorapplies the code, with a newamountwhen it changes the total, and anerrorrefuses it. If your handler throws, rejects, or doesn't answer within 10 seconds, the sheet refuses that code. Callupdate({ amount, lineItems, shippingOptions })to change what the sheet shows; while a sheet is open,update()throws, so answer the change events to change it.canMakePayment({ types })checks only the wallets you list, and its result includes each available wallet's official button art. (#33780) - a6450aa: The
emailandaddresselements takelabelMode: "floating", in both address layouts. Each field shows its label as the placeholder until it has a value, then the text moves down and a small label fades in above it.abovestays the default. (#33780) - prop "labelMode" added (
payments.address.props.labelMode) - prop "labelMode" added (
payments.email.props.labelMode) - resource option "requestPromoCode" added (
payments.paymentRequest.options.requestPromoCode) - resource option "appliedPromoCode" added (
payments.paymentRequest.options.appliedPromoCode) - resource option "appliedPromoDescription" added (
payments.paymentRequest.options.appliedPromoDescription) - resource method "update" added (
payments.paymentRequest.methods.update) - resource event "promoCodeChange" added (
payments.paymentRequest.events.promoCodeChange) - resource event failure answer "promoCodeChange" added (
payments.paymentRequest.replyFail.promoCodeChange) - resource live option "amount" added (
payments.paymentRequest.liveOptions.amount) - resource live option "lineItems" added (
payments.paymentRequest.liveOptions.lineItems) - resource live option "shippingOptions" added (
payments.paymentRequest.liveOptions.shippingOptions)
1.4.0
Minor Changes
- 9988376: When your Apple Pay or Google Pay change handler throws or rejects, the sheet now shows an error for that change right away. A
billingAddressChangehandler that throws, rejects, answers witherrors, or doesn't answer within 10 seconds now refuses that card, so the buyer picks another one; before, the sheet kept the current total. In PayPal, the same answers refuse the address the buyer picked. Apple Pay has no error slot for a shipping option, so a refused option keeps the last accepted total and the error shows when the buyer taps Pay. (#33706) - 9988376: The payment request can now open PayPal.
canMakePayment()reportspayPalwhere the account offers PayPal in the request's currency, the amount is within PayPal's limits, and the page is a whop.com page or a domain verified as a payment method domain for the account, andshow('paypal_express'), called synchronously in the buyer's press like Apple Pay and Google Pay, opens PayPal at the request'samount: a pop-up on desktop, PayPal's in-page window when the pop-up is blocked, and the in-page window on mobile. Each shipping address the buyer picks in PayPal firesbillingAddressChange, andshippingAddressChangetoo withrequestShipping, and the total your handlers answer is the one PayPal shows. PayPal has no billing address step of its own and may share only a country at approval, so the shipping address is what the total is taxed on; an error naming afieldrefuses that part of the address inside PayPal. WithrequestShipping, yourshippingOptionsappear in PayPal and the buyer's pick firesshippingOptionChange. The result arrives the same way as the other wallets, withtype: 'paypal_express'and, withrequestShipping, the address the buyer chose in PayPal asshipping; confirm it like the other wallets' tokens. The token pays at most the total PayPal showed the buyer, and closing PayPal rejectsshow()as a dismissal. PayPal pays one-time purchases and cannot collect a phone number, so a request withsetupFutureUsageorrequestPayerPhonereportspayPal: false, as does a page that already loads PayPal's own v5 JavaScript SDK. A page with a Content Security Policy must allowwww.paypal.com,c.paypal.com,api-m.paypal.com,www.paypalobjects.com,js.braintreegateway.com,assets.braintreegateway.comand*.braintree-api.com.canMakePayment()now always reportspayPal, andcanMakePayment().orderends withpaypal_express. (#33706) - 9988376: Express checkout can now offer a one-press PayPal button beside Apple Pay and Google Pay on one-time purchases, carts included, where the seller accepts it and the checkout does not need the buyer's phone number. PayPal opens on your page: in a pop-up on desktop, falling back to PayPal's in-page window when the pop-up is blocked, and in the in-page window on mobile. Like Apple Pay and Google Pay, it renders only on whop.com pages and on domains verified as payment method domains for the account, and a page with a Content Security Policy must allow
www.paypal.com,c.paypal.com,api-m.paypal.com,www.paypalobjects.com,js.braintreegateway.com,assets.braintreegateway.comand*.braintree-api.com. The purchase finishes without leaving the page. For each address the buyer picks, PayPal shows the checkout's own total, and PayPal shares the buyer's email and that address, which is what tax is computed on and, for physical goods, the shipping address. PayPal has no promo code entry of its own; a code the checkout already holds still applies. Thewalletsoption now acceptspaypal_expressand includes it by default; passwalletsto limit which buttons appear. (#33706) - 9988376: Added
contentSecurityPolicy(), which returns the sources your Content Security Policy must allow for elements, including the hosts the Apple Pay, Google Pay, and PayPal scripts reach, and merges them into your own policy string, directives object, or response headers.preloadHints()now also warms the Whop API connection and preloads the Apple Pay, Google Pay, and PayPal scripts. Passenvironment: "sandbox"for the sandbox API and each provider's sandbox hosts, andwallets: falseto either helper on pages that don't show Apple Pay, Google Pay, or PayPal. It still returns an array, now withtoLinkHeader(),toHtml(), andapplyTo(headers). (#33706) - resource event failure answer "billingAddressChange" added (
payments.paymentRequest.replyFail.billingAddressChange) - resource event failure answer "shippingAddressChange" added (
payments.paymentRequest.replyFail.shippingAddressChange) - resource event failure answer "shippingOptionChange" added (
payments.paymentRequest.replyFail.shippingOptionChange) - page-requirement group "wallets" added (connect:https://account.google.com, connect:https://api-m.paypal.com, connect:https://api-m.sandbox.paypal.com, connect:https://api.basistheory.com, connect:https://api.braintreegateway.com, connect:https://api.sandbox.braintreegateway.com, connect:https://google.com, connect:https://pay.google.com, connect:https://payments.braintree-api.com, connect:https://payments.sandbox.braintree-api.com, connect:https://www.google.com, connect:https://www.paypal.com, connect:https://www.sandbox.paypal.com, frame:https://assets.braintreegateway.com, frame:https://checkout.paypal.com, frame:https://www.paypal.com, frame:https://www.sandbox.paypal.com, image:https://www.paypalobjects.com, script:https://applepay.cdn-apple.com, script:https://c.paypal.com, script:https://js.braintreegateway.com, script:https://pay.google.com, script:https://www.paypal.com, script:https://www.sandbox.paypal.com) (
_pageRequirements.wallets)
Patch Changes
1.3.0
Minor Changes
- e84aa25: Payment request errors can point at the address field to fix: an error passed to
updateWithwith afield(city,state,postal_codeorcountry) marks that field in the Apple Pay sheet with your message. Google Pay shows the message alone. (#33110)
Patch Changes
- e84aa25: Withdrawal details now use compact cards for the source balance, payout destination, requester, fee and withdrawal ID. The timeline runs from oldest to newest, with upcoming stages in gray, descriptions for the current stage only, relative dates for today and yesterday, and date skeletons while updates load. (#33110)
- e84aa25: When a withdrawal goes to a bank account in the same currency but is converted along the way, the Withdraw confirmation now counts that conversion cost in Fees and explains the split in the fee's tooltip, so the fees and the amount received add up to the amount withdrawn. (#33110)
- e84aa25: Removed the separate withdrawal reason card so failure and cancellation reasons appear only in the timeline.
Moved the trace code and copy button below the current timeline description instead of a separate card. (#33110)
1.2.0
Minor Changes
- efef905: The balances list emits creditsSelected when the viewer selects the platform credits row. (#32750)
- efef905: Expose the Wallet onIdentityVerificationRequested callback so hosts can open their own settings or verification flow from deposit overlays. (#32750)
- controller event "identityVerificationRequested" added (
wallet.controller.events.identityVerificationRequested) - event "creditsSelected" added (
wallet.balances.list.events.creditsSelected)
Patch Changes
- efef905: The payment detail breakdown now adds up: each purchased item, then the subtotal, promo discount and tax charged on top, then what the customer paid; below it, refunds, tax Whop remitted and fees down to the net amount. Tax included in the price is noted under the total instead of being listed as a charge. (#32750)
1.1.0
Minor Changes
-
1e0807c: Added
defaultValues.billingDetailsto the payment element to prefill the billing name, address, and phone. (#31805) -
1e0807c: Added
defaultValuesto the checkout element to prefill the phone number, shipping address, and billing details.The address element and the payment element's billing details no longer prefill a street address under a different country when the prefilled country can't be used. Only the name is prefilled in that case. (#31805)
-
1e0807c: The address element can now be mounted once per
modeunder one Payments handle, so a checkout can collect a shipping address and a separate billing address. Billing details come from the billing element, or from the shipping element when no billing element is mounted. Each address element has its own autocomplete suggestions. An address element'smodeis now set when you create it. Changing it on a live element is ignored with a console warning; destroy the element and create a new one instead. (#31805) -
1e0807c: Track card-number copy requests in Whop Card analytics. (#31805)
-
1e0807c: The
Checkoutcontroller now firesonCompleteonce the purchase stands — before anyreturnUrlnavigation — so an embedding page can record the purchase in its own analytics or ad pixels. The payload names what stands:{ sessionId, result: 'payment', paymentId }for a paid checkout,{ result: 'waitlist_entry', entryId }for a waitlist join,{ result: 'setup', setupIntentId }for a saved payment method. (#31805) -
prop "defaultValues" added (
payments.payment.props.defaultValues) -
cardinality one → one per "mode" (
payments.address.keyedBy) -
controller event "complete" added (
checkout.controller.events.complete) -
prop "defaultValues" added (
checkout.checkout.props.defaultValues) -
event "cardNumberCopyRequested" analytics allowlist added (accountId,cardId) (
wallet.cards.whopCard.eventAnalytics.cardNumberCopyRequested)
Patch Changes
- 1e0807c: The campaign creator and the ads reporting table now take and show budgets in the account's
ads_reporting_currency, the same currency spend and results already report in. An account reporting in EUR enters €500 and reads €500 back on the campaign, the ad groups, and the inline budget editor; the API converts it to USD at the current exchange rate, which is what the budget is billed in. Nothing to configure on the element — set the account'sads_reporting_currencypreference and budgets follow it. USD accounts see no change. (#31805) - 1e0807c: Fixed opaque white backgrounds behind embedded elements on dark pages that declare a color-scheme meta tag. (#31805)
- 1e0807c: Fixed appearance styles dropping lab() and oklch() colors, including transparency, CSS variables, borders, and shadows. (#31805)
- 1e0807c: Fixed toasts raised inside embedded elements never appearing. (#31805)
1.0.0
Major Changes
- 4629eac: Initial release of Whop Elements — embeddable Whop UI for any website. Drop the
elements.jsscript tag (or install@whop/elements) and mount ready-made, themeable components that talk to Whop for you;@whop/elements-reactships first-class React bindings on top. This first release includes the full foundation: typed handles with liveupdate(), events and actions; light/dark theming and appearance customization; localized components; prerendered loading skeletons for flash-free first paints; modal and inline flow surfaces; and generated TypeScript types for the entire surface. (#30895) - 4629eac: Added the payments
brandingelement — the "Powered by Whop" notice with terms and privacy links. It is required: the other payments elements stay in their loading state until it is mounted, and payments cannot be confirmed without it — a missing branding mount failscreateConfirmationTokenwith the codedBRANDING_NOT_MOUNTEDerror, and one the embedding page hides or shrinks away fails withBRANDING_HIDDEN. Breaking for existing payments integrations: mountbrandingalongside your other payments elements when you upgrade. (#30895) - 4629eac: Removed the campaign builder's
showToastsprop anderroredevent. Failure toasts now always appear exactly once through the standard toast surface — on your own page when the builder is embedded — so there is nothing left to mirror or turn off. (#30895) - 4629eac: Choose which Whop environment your elements run against when you create them:
WhopElements({ environment: 'sandbox' })uses test data with no real money moving, and production is the default. This is the one setting that decides where the elements send what a buyer enters — they only ever talk to Whop. (#30895)
Minor Changes
-
4629eac: The embedded campaign builder shows the merchant when something fails: a refused launch, a failed upload or a draft that would not save renders as a toast in the builder itself, and comes back on an
erroredevent if your page wants to log it or show it its own way. (#30895) -
4629eac: The ads reporting table gained a
linkClickscolumn — clicks on links in the ad that lead to your destination, as reported by the ad platform, next to the broaderclickscount. Off by default; turn it on from the column picker or by passing it incolumns, and it comes back incolumnsChangedlike any other column. (#30895) -
4629eac: Bank wire payout methods now show the destination-currency country flag on the bottom-right of the card icon, so AED, EUR, and other wires are distinguishable in the method picker. (#30895)
-
4629eac: The checkout offers one-press express checkout: Apple Pay and Google Pay buttons above the form, shown when the wallet is available on the buyer's device and the page's origin is approved for the account. The wallet sheet collects whatever the checkout still needs — the buyer's email, and the shipping address when the purchase requires one — and the buttons stack best-first for the browser: Apple Pay first on Safari and iOS, Google Pay first elsewhere. (#30895)
-
4629eac: Added the express checkout element — one-press Apple Pay and Google Pay buttons you can mount on their own under a checkout handle (
checkout.create("expressCheckout"), or<ExpressCheckoutElement/>in React). The OS payment sheet collects the buyer's email and shipping address when the session needs them, so one press finishes the purchase. It shares the checkout's entry slot with the checkout element: a handle mounts exactly one of the two. Two options shape it:walletspicks which wallet buttons may render (a filter over what the buyer's device actually offers — the element never shows a wallet the device can't pay with), andlayoutcontrols how the buttons stack (autofollows the container,horizontalandverticalforce one arrangement). (#30895) -
4629eac: Added Bitcoin deposits to the Deposit element, with a reusable BTC address and direct settlement as USDT0 on Plasma. (#30895)
-
4629eac: Collect Splitit's required billing phone once, show missing-phone feedback, and submit the collected or caller-supplied number with the payment method.
Use one simple phone input for Splitit and reuse a phone already collected by checkout. Add
fields.phoneto disable duplicate collection andchange.requiresBillingPhoneto expose the selected method’s requirement. (#30895) -
4629eac: Added an
rfielement to the verifications namespace: it lists everything an account still owes compliance, grouped by what each requirement affects, and collects the answers in place. (#30895) -
4629eac: Added the verifications namespace and its complete verification element. It collects KYC or KYB intake details, starts or resumes the hosted provider session, answers follow-up information and document requests, polls status, and renders the result using the 2026-08-05 API version. The hosted provider step opens in a secure tab so camera and document access work from embedded integrations. (#30895)
-
4629eac: Checkout element: buyers are charged in their own currency, not shown a converted price. The server picks the currency from where the checkout was opened and publishes the one alternative as a "Pay in USD instead" switch. A converted total discloses what it converted from and at what locked rate, to five significant digits ("1 USD = 0.92191 EUR"), and when a promo code is applied the original price is struck through in the currency the buyer actually pays. (#30895)
-
4629eac: How a checkout finishes: when you set a
returnUrl, a completed purchase redirects the page the element is embedded in straight to it — fulfill from webhooks, which are the source of truth for a landed payment — and a page whose sandbox blocks that navigation gets a Continue button that makes the same trip. A payment step that leaves the page, like 3D Secure or a bank page, carries the buyer back to a page that tells them exactly where the order stands. Completion is judged by the payment's own status: a payment that settles later, like a bank debit, shows clearing copy while the money is still moving and only sends the buyer on once it has genuinely settled, and a dismissed 3D Secure dialog rests on a "Finish your payment" button. (#30895) -
4629eac: The checkout element now takes
buyerEmailandlockBuyerEmailon embedded mounts too — pass the email your page already collected (checkout.create("checkout", { buyerEmail }), or<CheckoutElement buyerEmail={…} />) and the email row is seeded with it; addlockBuyerEmailto keep the buyer from editing it. Both were direct-mode props before, so a third-party page migrating from the legacy embedded checkout'sprefill.emailhad no way to prefill the buyer's email. A session that already holds its buyer's email still wins over the prefill, exactly as on whop.com's own checkout page. (#30895) -
4629eac: Checkout now accepts an
itemsarray so one checkout can sell multiple plans and quantities in a single payment. Multi-item checkouts show every server-priced item directly below the total, while the existingplanandquantityoptions continue to work as the single-item shorthand. (#30895) -
4629eac: Added the tax ID element to the payments namespace: a standalone registration collector with a type select covering every registration the API accepts — labeled the way buyers know them (EU VAT, AR CUIT, US EIN, …) — and a value input whose placeholder follows the selected type. When you pass the buyer's country it preselects the right type. The checkout element's company-purchase section composes it, so a business buyer can enter any accepted tax ID at checkout: the total re-prices with the reverse charge applied where it applies, and the charge is taxed under the same registration. (#30895)
-
4629eac: The checkout element says what the two special checkouts actually are. Opening a transfer link states in the order summary that you are accepting an existing membership — nothing is charged today, when the inherited access ends, and when the payment method you add first renews. A waitlist join tells the whole truth about money: the total reads "If accepted" rather than "Due today", the terms explain the buyer is only charged if the seller accepts their request, and a completed join says you are on the waitlist — the seller reviews requests, and the saved payment method is only charged if they accept you — both inside the element and on the hosted return page. A completed join is also announced to an embedding iOS/Android app so its checkout sheet closes. (#30895)
-
4629eac: Added default activity type filters so embedded activity feeds can open scoped to flows such as card spend, reversals, and refunds. (#30895)
-
4629eac: The balance breakdown can now sit inside a surface that already has its own heading:
showTotalhides its currency title and total, andpadded...