Install
The SDK supports iOS 15 and later. Swift Package Manager. In Xcode: File → Add Package Dependencies…, paste the repository URL and add the MeldSDK library to your app target.import MeldSDK.
MeldSDK depends on Stripe’s StripeCryptoOnramp 26.11.x and on PrimerSDK 2.49 or a later 2.x, even if you use neither Stripe nor Banxa. An app that already depends on a different minor version of Stripe’s iOS SDK cannot resolve both.
Configure the environment
Create the order on your backend
The order comes from your server. Your API key never ships in the app binary. See Cards or Apple Pay for the request. Return the response to the app unchanged: the SDK reads what it needs from it.Mount the order
mount on the main thread. Pass into: a view you own for an embedded card widget. Apple Pay and Stripe orders draw nothing into it, so into: is optional for them. Without it, a Stripe or Coinbase order presents from your app’s single foreground window, and mount throws if there is none. In an app with several windows, pass into: a view in the window to present from.
Apple Pay uses the same call with an applePay: argument — see Apple Pay.
Keep the handle until a terminal callback. Releasing it tears the surface down, and handle.unmount() does the same on demand. Neither delivers a callback.
To check a quote before you create the order, decode its headlessPresentation with MeldHeadlessPresentation(json:) and pass it, with the paymentMethodType, to Meld.capabilities(for:paymentMethodType:). That tells you only whether this build can present that kind of order. Check the order itself again before you mount it.
Events
The five events covers what each one means, how
onCancel and onError relate to the status, and the rule that each mount ends with exactly one terminal callback. To retry after a terminal callback, create a new order.
Error codes
Apple Pay and Stripe orders report these codes. Embedded card widgets report their own, some withrecoverable: true.
error.attemptMayExist is false for every code above except PAYMENT_OUTCOME_UNKNOWN. Treat any other non-recoverable code, including one this table doesn’t list, like PAYMENT_OUTCOME_UNKNOWN.
detail carries the provider’s own event or code. Log it; don’t branch on it.
Permissions
Providers that run KYC inside their surface need camera access, and so does Stripe’s identity check. DeclareNSCameraUsageDescription in your Info.plist with a string that explains the document and selfie capture. Without it, that step fails silently for the user, or, on a Stripe order, the SDK refuses it and the flow ends in onError.
Apple Pay needs the Apple Pay capability on your target, listing every merchant identifier an order can carry, including both your Stripe sandbox and live identifiers. Apple Developer setup covers which providers need one.
Provider notes
The sameMeld.mount call presents every provider’s order. A few providers add requirements of their own:
- Stripe.
onReadyfires before anything is on screen, because the SDK shows nothing until it needs the customer. Keep your own busy state until a terminal callback, and block anything that would unmount the SDK or start another order meanwhile.- One Stripe order runs at a time. After you unmount one before its terminal callback, a new one can report
PRESENTATION_FAILEDfor up to 90 seconds. - Stripe’s SDK runs only in an app Stripe has registered as a trusted application, and production orders need a physical device. When you run one from Xcode, set the
com.apple.developer.devicecheck.appattest-environmententitlement toproduction. - On an Apple Pay order, an
applePay:you pass must match the order’s amount, inUSD, ormountthrows.
- Coinbase. It needs iOS 16 or later: below that,
Meld.capabilities(for:)reportsunsupported.applePay:is ignored. If you passinto:, keep that view in its window until a terminal callback.
Settlement
Settlement is your webhook.onPaymentSubmitted fires when the user finishes paying, which is earlier: unmount and show a pending state until the webhook arrives.
See Configure webhooks.