rnw-community / rnw-community

NestJS, ReactNative, React packages for your projects
MIT License
55 stars 9 forks source link

react-native-payments: 0 should be an allowed amount #208

Closed mathieubruguier closed 1 week ago

mathieubruguier commented 3 months ago

Good day,

The MDN documentation for PaymentRequest never mentions 0 being a forbidden total amount. The constructor for PaymentRequest in react-native-payments specifically checks for 0 and throws an error if that's the case: https://github.com/rnw-community/rnw-community/blob/master/packages/react-native-payments/src/util/validate-total.util.ts#L20

Having a total of $0 may seem counter-intuitive, but it's sometimes used to check if a payment method is valid (when changing a payment method for long-term payments for example). The flow works as expected with a total of $0 for Apple Pay (tested myself).

It might be an issue with Google Pay, but Apple Pay handles it gracefully. Here's the workaround I had to do in my codebase:

    const paymentDetails = {
      total: {
        label: applePayRequest.total.label,
        amount: {
          currency: applePayRequest.currencyCode,
          // The library does not support a total amount of 0 (even though it is valid in the spec)
          // So we set it to 0.01 if the total amount is 0
          // The reason for 0 being an option in the first place is during our "Update Payment Method" flow
          // where we want to update the payment method without charging the user
          value:
            applePayRequest.total.amount === '0'
              ? '0.01'
              : applePayRequest.total.amount,
        },
      },
      displayItems: [],
    };

    const paymentRequest = new PaymentRequest(methodData, paymentDetails);
    // Since the constructor above throws an error if the total amount is 0, we need to set it to 0 here
    // Hacky, but it works
    if (applePayRequest.total.amount === '0') {
      paymentRequest.details.total.amount.value = '0';
    }
vitalyiegorov commented 1 month ago

Maybe you should try using canMakePayment method from the standard

vitalyiegorov commented 1 week ago

@mathieubruguier Have you tried canMakePayment ?

vitalyiegorov commented 1 week ago

Closing due to missing response