// @ts-ignore import { ApplePayButton, PaymentRequest } from '../react_native_apple_pay'; import { debugLog, errorLog } from '../helpers/debug_log'; import { Platform, useColorScheme, View } from 'react-native'; import type { ApplePayProps } from '../models/component_models/moyasar_props'; import { toMajor } from '../helpers/currency_util'; import { assert } from '../helpers/assert'; import { ApplePayRequestSource } from '../models/api/sources/apple_pay/apple_pay_request_source'; import type { PaymentConfig } from '../models/payment_config'; import { PaymentRequest as MoyasarPaymentRequest } from '../models/api/api_requests/payment_request'; import { createPayment } from '../services/payment_service'; import { isMoyasarError, GeneralError, NetworkError, } from '../models/errors/moyasar_errors'; import type { ResultCallback } from '../models/payment_result'; // TODO: Move to service module export async function onApplePayResponse( token: any, paymentConfig: PaymentConfig, onPaymentResult: ResultCallback ) { const source = new ApplePayRequestSource({ applePayToken: token, manualPayment: paymentConfig.applePay?.manual, saveCard: paymentConfig.applePay?.saveCard, }); const paymentRequest = new MoyasarPaymentRequest({ givenId: paymentConfig.givenId, baseUrl: paymentConfig.baseUrl, amount: paymentConfig.amount, currency: paymentConfig.currency, description: paymentConfig.description, metadata: paymentConfig.metadata, source: source, applyCoupon: paymentConfig.applyCoupon, splits: paymentConfig.splits, }); debugLog('Moyasar SDK: Paying with Apple Pay...'); try { const paymentResponse = await createPayment( paymentRequest, paymentConfig.publishableApiKey ); onPaymentResult(paymentResponse); } catch (error) { errorLog(`Moyasar SDK: Failed to pay with Apple Pay, ${error}`); if (isMoyasarError(error)) { onPaymentResult(error); } else { onPaymentResult( new NetworkError( 'Moyasar SDK: An error occured error while processing an Apple Pay payment' ) ); } } } export function ApplePay({ paymentConfig, onPaymentResult, style, }: ApplePayProps) { assert( !!paymentConfig.applePay, 'Apple Pay config is required to use Apple Pay, you have to configure the `applePay` property in the `PaymentConfig` object' ); const isLightTheme = useColorScheme() === 'light'; if (Platform.OS !== 'ios' || !paymentConfig.applePay) { debugLog( 'Moyasar SDK: Apple Pay is not supported on this device or the `applePay` property is not set, showing empty view' ); return ; } assert(paymentConfig.applePay !== undefined, 'Apple Pay config is required'); return ( { debugLog('Moyasar SDK: Apple Pay button pressed'); const methodData = { supportedMethods: ['apple-pay'], // TODO: Test what happens if the merchantId was not set data: { merchantIdentifier: paymentConfig.applePay?.merchantId, supportedNetworks: paymentConfig.supportedNetworks, countryCode: paymentConfig.merchantCountryCode, currencyCode: paymentConfig.currency, }, }; const details = { total: { label: paymentConfig.applePay?.label, amount: { currency: paymentConfig.currency, value: toMajor(paymentConfig.amount, paymentConfig.currency), }, }, }; const applePayPaymentRequest = new PaymentRequest( [methodData], details ); debugLog( `Moyasar SDK: Apple Pay request: ${JSON.stringify(applePayPaymentRequest)}` ); applePayPaymentRequest .show() .then(async (paymentResponse: any) => { debugLog('Moyasar SDK: Got Apple Pay response'); if (paymentResponse.details.paymentData) { await onApplePayResponse( paymentResponse.details.paymentData, paymentConfig, onPaymentResult ); // TODO: Better handle completion based on `onApplePayResponse` response paymentResponse.complete('success'); } else { errorLog( 'Moyasar SDK: Apple Pay token is null, please use a physical device in order to test Apple Pay' ); paymentResponse.complete('failure'); onPaymentResult( new GeneralError( 'Moyasar SDK: Apple Pay token is null, are you using a Simulator? Please file a bug report if you are not' ) ); } }) .catch((error: any) => { // TODO: Should we call the `onPaymentResult` callback here? errorLog(`Moyasar SDK: Apple Pay payment error: ${error}`); }); }} /> ); }