Discount codes and payment links
Use native getDiscountedPaymentLinks and Web validateDiscountCode with exact offering selection and correct output handling.
Validation alone doesn't purchase, redeem a code or alter cached prices. The server revalidates eligibility and amounts when payment starts.
Kotlin: code-only payment links
The only input is the code string. Invalid codes are successful business results with isValid == false; network/database errors are failures. Output includes validity, code, errorCode, percent and eligible paymentLinks. Opening an allowed link continues existing Web payment; it doesn't discount the offering cache.
Flutter: convenience and Result
Convenience getDiscountedPaymentLinks(code, offeringIdentifier: ...) returns a nullable model. The optional selector defaults to null and selects an offering only on Web. Android/iOS retain code-only links; passing a selector does not retarget them.
ValidateDiscountCodeData preserves offering, code, isValid, errorCode, paymentLinks. Inspect fields according to platform; success/non-null alone does not mean the code is valid.
Web: discount the placement's selected offering
Omitted identifier in validateDiscountCode(code) selects current. An explicit identifier validates that offering. Never convert empty/invalid input to omission or retry against default. JS returns discount plus a separately priced offering; don't replace SDK current/base catalog with it.
On Flutter Web, pass selectedOffering.identifier to getDiscountedPaymentLinksResult and use its returned offering/code with createCheckout. Flutter's InappifyPurchaseParams has no discountCode input; displaying a discount doesn't apply it to payment. See the Flutter Web checkout example.
Avoid these mistakes
Don't submit a client-computed discount as server price authority, report server failure as invalid code, substitute another offering, or rebuild the checkout independently from its original package context.