Skip to content

Commit

Permalink
feat: add token & paymentMethodId handling to confirmPayment for Cards (
Browse files Browse the repository at this point in the history
  • Loading branch information
charliecruzan-stripe committed May 10, 2022
1 parent e0e651d commit 93dcdac
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,31 @@ class PaymentMethodCreateParamsFactory(

@Throws(PaymentMethodCreateParamsException::class)
private fun createCardPaymentSetupParams(): ConfirmSetupIntentParams {
val paymentMethodId = getValOr(paymentMethodData, "paymentMethodId", null)
val token = getValOr(paymentMethodData, "token", null)
val cardParams = cardFieldView?.cardParams ?: cardFormView?.cardParams
?: throw PaymentMethodCreateParamsException("Card details not complete")

val paymentMethodCreateParams =
PaymentMethodCreateParams.create(cardParams, billingDetailsParams)
if (paymentMethodId != null) {
return ConfirmSetupIntentParams.create(
paymentMethodId,
clientSecret
)
}

return ConfirmSetupIntentParams
.create(paymentMethodCreateParams, clientSecret)
val paymentMethodCreateParams =
if (token != null)
PaymentMethodCreateParams.create(PaymentMethodCreateParams.Card.create(token), billingDetailsParams)
else if (cardParams != null)
PaymentMethodCreateParams.create(cardParams, billingDetailsParams)
else
null

if (paymentMethodCreateParams != null) {
return ConfirmSetupIntentParams
.create(paymentMethodCreateParams, clientSecret)
} else {
throw PaymentMethodCreateParamsException("Card details not complete")
}
}

@Throws(PaymentMethodCreateParamsException::class)
Expand Down
2 changes: 1 addition & 1 deletion e2e/payments.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ describe('Common payment scenarios', () => {
cardField.setExpiryDate('12/22');
cardField.setCvcNumber('123');

getElementByText('Save').click();
getElementByText('Save via card input form').click();
const alert = getElementByText('Success');
alert.waitForDisplayed({
timeout: 20000,
Expand Down
98 changes: 94 additions & 4 deletions example/src/screens/SetupFuturePaymentScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
useConfirmPayment,
useConfirmSetupIntent,
useStripe,
createToken,
createPaymentMethod,
} from '@stripe/stripe-react-native';
import { API_URL } from '../Config';
import Button from '../components/Button';
Expand Down Expand Up @@ -61,8 +63,7 @@ export default function SetupFuturePaymentScreen() {
return { clientSecret, error };
};

const handlePayPress = async () => {
console.log('email', email);
const handlePayPressUsingForm = async () => {
// 1. Create setup intent on backend
const clientSecret = await createSetupIntentOnBackend(email);

Expand Down Expand Up @@ -101,6 +102,83 @@ export default function SetupFuturePaymentScreen() {
}
};

const handlePayPressUsingToken = async () => {
const clientSecret = await createSetupIntentOnBackend(email);

const { error: tokenError, token } = await createToken({
type: 'Card',
name: 'David Wallace',
currency: 'usd',
});

if (tokenError) {
Alert.alert(`Error code: ${tokenError.code}`, tokenError.message);
console.log('Setup intent confirmation error', tokenError.message);
return;
}

const { error, setupIntent: setupIntentResult } = await confirmSetupIntent(
clientSecret,
{
paymentMethodType: 'Card',
paymentMethodData: {
token: token?.id,
},
}
);

if (error) {
Alert.alert(`Error code: ${error.code}`, error.message);
console.log('Setup intent confirmation error', error.message);
} else if (setupIntentResult) {
Alert.alert(
'Success',
`Setup intent created. Intent status: ${setupIntentResult.status}`
);

setSetupIntent(setupIntentResult);
}
};

const handlePayPressUsingID = async () => {
const clientSecret = await createSetupIntentOnBackend(email);

const { error: e, paymentMethod } = await createPaymentMethod({
paymentMethodType: 'Card',
});

if (e) {
Alert.alert(`Error code: ${e.code}`, e.message);
console.log('Setup intent confirmation error', e.message);
return;
} else if (!paymentMethod) {
Alert.alert(`Something went wrong creating the payment method.`);
return;
}

const { error, setupIntent: setupIntentResult } = await confirmSetupIntent(
clientSecret,
{
paymentMethodType: 'Card',
paymentMethodData: {
paymentMethodId: paymentMethod.id,
},
}
);

if (error) {
Alert.alert(`Error code: ${error.code}`, error.message);
console.log('Setup intent confirmation error', error.message);
} else if (setupIntentResult) {
Alert.alert(
'Success',
`Setup intent created. Intent status: ${setupIntentResult.status}`
);

setSetupIntent(setupIntentResult);
}
};

// It's only for example purposes
// This action is responsible for charging your previously added card and should be called independently of the payment flow.
const handleOffSessionPayment = async () => {
Expand Down Expand Up @@ -204,8 +282,20 @@ export default function SetupFuturePaymentScreen() {
<View style={styles.buttonContainer}>
<Button
variant="primary"
onPress={handlePayPress}
title="Save"
onPress={handlePayPressUsingForm}
title="Save via card input form"
loading={loading}
/>
<Button
variant="primary"
onPress={handlePayPressUsingToken}
title="Save via token"
loading={loading}
/>
<Button
variant="primary"
onPress={handlePayPressUsingID}
title="Save via payment method ID"
loading={loading}
/>
</View>
Expand Down

0 comments on commit 93dcdac

Please sign in to comment.