react-square-web-payments-sdk icon indicating copy to clipboard operation
react-square-web-payments-sdk copied to clipboard

feat: Split out card button to allow custom buttons

Open alexbrazier opened this issue 11 months ago • 0 comments

Your checklist for this pull request

🚨Please review the guidelines for contributing to this repository.

  • [x] Make sure you are requesting to pull a topic/feature/bugfix branch (right side). Don't request your master!
  • [x] Make sure you are making a pull request against the main branch (left side). Also you should start your branch off our main.
  • [x] Check the commit's or even all commits' message styles matches our requested structure.
  • [x] Check your code additions will fail neither code linting checks nor unit test.

Description

  • Split out the credit card payment button, closes #67
  • Export useForm
    • This allows you to access the payment methods which lets you save card details and charge again them next time
  • Provide payment instance to cardTokenizeResponseReceived to allow saving card and reverifying buyer

e.g.

Separate payment button

import { PaymentForm, CreditCard, CreditCardButton } from 'react-square-web-payments-sdk';

const Payment = ({ formProps }) => {
  return (
    <PaymentForm {...formProps}>
      <h1>Pay</h1>
      <CreditCard hideButton />
      <p>Some other stuff in the middle, e.g. other payment methods</p>
      <CreditCardButton />
    </PaymentForm>
  );
};

Saved card example:

import { PaymentForm, CreditCard, CreditCardButton, useForm } from 'react-square-web-payments-sdk';

const Payment = ({ formProps, savedCard }) => {
  return (
    <PaymentForm {...formProps}>
      <h1>Pay</h1>
      <p>Pay with {savedCard}</p>
      <SavedCardButton formProps={formProps} savedCard={savedCard} />
    </PaymentForm>
  );
};

const SavedCardButton = ({ formProps, savedCard }) => {
  const form = useForm();
  const submit = () => {
    const verifyBuyerResults = await paymentForm.payments?.verifyBuyer(
      savedCard,
      formProps.createVerificationDetails()
    );

    await paymentForm.cardTokenizeResponseReceived(
      { token: savedCard, status: "OK" },
      verifyBuyerResults
    );
  };

  return <Button onClick={submit}>Pay with saved card</Button>;
};

Save payment card

import { PaymentForm } from "react-square-web-payments-sdk";

const Payment = ({ formProps }) => {
  const [saveCard, setSaveCard] = useState(false);
  return (
    <PaymentForm
      {...formProps}
      verificationDetails={() => ({
        ...formProps.verificationDetails,
        intent: saveCard ? "STORE" : "CHARGE",
      })}
      cardTokenizeResponseReceived={async (token, buyer, payments) => {
        let cardToken = token.token;
        let buyerToken = buyer?.token;
        if (saveCard) {
          const result = await api.post("/save-card", { cardToken, buyerToken });
          // Token received from square with the saved card token
          cardToken = result.data.savedCard;

          const verifyResult = await payments?.verifyBuyer?.(cardToken, {
            ...formProps.verificationDetails,
            intent: "CHARGE",
          });

          buyerToken = verifyResult?.token;
        }

        await api.post("/pay", { cardToken, buyerToken });
      }}
    >
      <h1>Pay</h1>
      <p>Pay with {savedCard}</p>
      <CreditCard />
      <input value={saveCard} onChange={e => setSaveCard(e.target.checked} type="checkbox" />
    </PaymentForm>
  );
};

alexbrazier avatar Mar 06 '24 21:03 alexbrazier