Stripe Payment Intents 및 Next 를 사용합니다.회사 명

2019년 9월 14일, Stripe는 새로운 유럽 입법에 부합하기 위해 지불을 처리하는 API를 출시했다.Stripe를 사용하고 있다면, 지불 의도까지 실현했다는 말을 들었을 수도 있습니다.
새로운 변화를 따르지 않는 회사들은 은행이 거래를 거절하고 고객을 속이는 것을 보고 매출을 줄일 수 있다.📉
만약에 귀하의 기업이 유럽 경제구에 위치하거나 유럽 경제구에 있는 모든 사람에게 지불하고 유럽 경제구의 고객에게 서비스를 제공하고 신용카드나 차용카드를 수락한다면 귀하는 Strong Customer Authentication을 준수해야 합니다.
결제 처리의 변화로 인해 이전처럼 전면에서 결제를 만들 수 없습니다.현재 스트라이프가 있는 지불을 만들기 위해 서버 요소가 있어야 합니다.
이 가이드에서는 Next에서 새로운 Stripe Payment Intents API를 사용하는 방법을 설명합니다.Stripe 및 업계 규정에 따른 모범 사례
너무 길어서 읽을 수가 없어요.Get the code

선결 조건

  • A Stripe 계좌
  • 줄무늬 Secret keyPublishable key
  • React & Next에 대해 알아보십시오.js
  • 만약 네가 영상 형식을 따르기를 원한다면, 나는 이 문장에 관한 짧은 동영상을 녹음했다.

    시작하다


    다음을 사용합시다.js CLI에서 새 프로젝트 및 템플릿을 작성합니다.
    npm init next-app # or yarn create next-app
    
    의존 항목을 설치하면 cd을 프로젝트 폴더에 넣습니다.
    현재 파일을 만듭니다. pages/checkout.js 다음 내용을 추가합니다.
    const CheckoutPage = props => (
      <pre>{JSON.stringify(props, null, 2)}</pre>
    );
    
    export default CheckoutPage;
    
    현재 npm run dev (또는 yarn dev) 을 실행하면 페이지에 빈 props 대상이 표시됩니다.
    ⚠️ Stripe는 금액을 알고 고객이 결제 절차를 시작하는 즉시 결제 의향을 작성하는 것을 권장합니다.사용자가 나중에 사이트로 돌아가 이전과 동일한 카트 또는 주문 결제를 완료할 경우 결제 의도를 검색할 수도 있습니다.
    이제 계속합시다...이렇게 해!👯‍♀️

    서버 측


    Next.js 9.3.0 introduceda 우리는 새로운 getServerSideProps 생명주기 방법을 사용하여 서버 쪽만 하는 행위를 실행할 수 있다.
    이것은 우리가 더 이상 API 루트를 만들어서 창설 의도를 처리하고 서명 페이지에서 직접 처리할 필요가 없다는 것을 의미한다.
    테이프 설치부터 시작합시다.js 의존성;
    npm install stripe # or yarn add stripe
    
    그리고 pages/checkout.js 페이지에서 파일 맨 위에 있는 Stripe 패키지를 가져옵니다.
    import Stripe from "stripe";
    
    현재 getServerSideProps 방법에 연결하려면 const으로 내보내야 합니다.
    이 방법에서, 우리는 우리의 지불 의도를 만들 것이다.이 강좌에서 우리는 amountcurrency의 값을 복원할 것입니다. 그러나 이 방법에서, 나는 fetch의 요청을 보내서 쇼핑 카트의 총수를 찾을 것을 건의합니다.사용자가 자신의 amountcurrency을 제공할 수 있도록 허용하지 않는 한😀.
    ⚠️ Developer API Keys Dashboard으로 이동하여 다음 키를 복사하십시오.

    결제 의도 작성


    export const getServerSideProps = async () => {
      const stripe = new Stripe("STRIPE_SECRET_KEY_HERE");
    
      const paymentIntent = await stripe.paymentIntents.create({
        amount: 1000,
        currency: "gbp"
      });
    
      return {
        props: {
          paymentIntent
        }
      };
    };
    
    👀 현재 로그인하고 email 또는 shipping 주소를 알고 있는 고객과 같은 더 많은 정보를 알고 있으면 create 함수로 전달할 수 있습니다.너는 줄무늬 파일에서 full list of arguments을 볼 수 있다.
    다음은 npm run dev(또는 yarn dev)으로 다음 개발 서버를 시작하고 http://localhost:3000/checkout 으로 이동합니다.
    🎉 예!너는 지불 의향 대상을 보아야 한다.
    ⚠️ 비록 이것은 매우 좋지만, 매번 당신이 이 페이지를 방문할 때마다 새로운 지불 의도를 만들 것입니다. 우리가 전에 언급한 바와 같이, 이렇게 하는 것을 건의하지 않습니다.

    기존 결제 의도 검색

    getServerSideProps은 검사할 수 있는 쿠키를 저장하는 곳입니다. 기존 ID가 있으면 Stripe를 호출하여 지불 의도를 검색하십시오.
    Next를 사용하여 쿠키를 해석하고 설정하려면 nookies을 설치합니다.js 상하문;
    npm install nookies # yarn add nookies
    
    그리고 pages/checkout.js을 업데이트하여 nookies 의존항을 가져옵니다.
    import { parseCookies, setCookie } from "nookies";
    
    현재 getServerSideProps을 (으)로 업데이트합니다.
    export const getServerSideProps = async ctx => {
      const stripe = new Stripe("STRIPE_SECRET_KEY_HERE");
    
      let paymentIntent;
    
      const { paymentIntentId } = await parseCookies(ctx);
    
      if (paymentIntentId) {
        paymentIntent = await stripe.paymentIntents.retrieve(paymentIntentId);
    
        return {
          props: {
            paymentIntent
          }
        };
      }
    
      paymentIntent = await stripe.paymentIntents.create({
        amount: 1000,
        currency: "gbp"
      });
    
      setCookie(ctx, "paymentIntentId", paymentIntent.id);
    
      return {
        props: {
          paymentIntent
        }
      };
    };
    
    참고: 스트라이프 암호를 STRIPE_SECRET_KEY_HERE으로 덮어쓰지 마십시오.🤪 복사/붙여넣기!
    분명히 구현은 사용자의 설정에 따라 다를 수 있지만, 본 강좌의 목적은 교수 절차와 최선의 실천이다.
    현재 http://localhost:3000/checkout으로 되돌아와 갱신하면 같은 지불 의도를 보실 수 있습니다!🎉
    [Stripe Dashboard]에서 만든 결제도 볼 수 있습니다./checkout 페이지를 불러오는 횟수에 따라 2번 이상 지불을 보실 수 있습니다.최근의 것은 쿠키에 다시 사용되고 저장될 것이다.

    테이프는 paymentIntents.create()에 보내는 요청 매개 변수를 포함하여 지불과 관련된 모든 활동을 보여 줍니다.

    클라이언트


    이제 사용자 카드를 포착하고 지불을 처리할 때가 되었다.스트라이프 결제 의도 API는 거래를 처리하려면 paymentMethod이 필요합니다.
    우리는 클라이언트 테이프 라이브러리를 사용하여 안전한 paymentMethod을 만들 수 있습니다. 여기에는 우리의 카드 정보를 포함하고 테이프에 전달할 수 있습니다.
    프런트엔드에 종속 항목 설치:
    npm install @stripe/stripe-js @stripe/react-stripe-js # or yarn add @stripe/stripe-js @stripe/react-stripe-js
    

    프런트엔드에 스트라이프 구성


    이제 이 파일을 설치한 후 pages/checkout.js 파일의 맨 위에 다음 가져오기 줄을 추가합니다.
    import { loadStripe } from "@stripe/stripe-js";
    import { Elements } from "@stripe/react-stripe-js";
    
    우리는 Promise 제공 프로그램을 전달하기 위해 테이프 Elements을 만들어야 합니다.Stripe Dashboard의 발표 가능한 키가 필요합니다. CheckoutPage 함수에 다음 내용을 추가합니다.
    const stripePromise = loadStripe("STRIPE_PUBLISHABLE_KEY");
    
    마지막으로 CheckoutPage 함수를 업데이트하고 Elements과 새로 만든 stripePromise Promise로 페이지를 포장합니다.
    const CheckoutPage = props => {
      return (
        <Elements stripe={stripePromise}>
          <pre>{JSON.stringify(props, null, 2)}</pre>
        </Elements>
      );
    };
    

    체크 아웃 양식 만들기


    계속해서 프로젝트의 루트 디렉터리에 폴더/파일 components/CheckoutForm.js을 만들고 다음과 같은 내용을 추가합니다.
    import React from "react";
    
    const CheckoutForm = ({ paymentIntent }) => {
      const handleSubmit = async e => {
        e.preventDefault();
      }
    
      return (
        <form onSubmit={handleSubmit}>
          {/* TODO */}
        </form>
      );
    }
    
    export default CheckoutForm
    
    이것은 기본적으로 CheckoutForm의 설정을 위한 기초입니다. pages/checkout.js 페이지에서 가져오고 호출해야 합니다.
    // pages/checkout.js
    
    import CheckoutForm from "../components/CheckoutForm";
    
    CheckoutPage 함수를 업데이트하여 paymentIntentprops에서 CheckoutForm으로 전달합니다.
    // pages/checkout.js
    const CheckoutPage = ({ paymentIntent }) => (
      <Elements stripe={stripePromise}>
        <CheckoutForm paymentIntent={paymentIntent} />
      </Elements>
    );
    
    ⚠️ 어떤 이유로든 paymentIntent이 존재하지 않습니다. 사용자에게 메시지를 표시하기를 원할 수도 있습니다.

    스트라이프 반응 연결 사용하기

    @stripe/react-stripe-js은 새로운 Stripe 라이브러리로 우리가 사용할 수 있는 편리한 연결고리와 구성 요소를 공개했다.우리는 사용할 것이다.
  • CardElement
  • useStripe
  • useElements
  • CheckoutForm 함수에서 우리는 이 두 개의 테이프 연결을 호출할 것이다. 따라서 우리는 stripeelements에 대한 인용을 가지고 다음 handleSubmit 함수에서 사용할 수 있도록 한다.
    const CheckoutForm = ({ paymentIntent }) => {
      const stripe = useStripe();
      const elements = useElements();
    
      // ... rest of file
    }
    

    React 연결로 스트라이프 의도 확인


    우리가 stripe에서 사용해야 할 방법은 confirmCardPayment 으로 3개의 파라미터를 받아들인다.client_secret 및 (옵션: dataoptions).
    우리는 이미 client_secretpaymentIntent 내부에서 pages/index.js getServerSideProps으로 전달한 후 도구를 통해 CheckoutForm으로 전달했다.handleSubmit 함수를 업데이트하여 지불 의도를 확인하기 위해 Stripe에 요청을 보냅니다.
    const handleSubmit = async e => {
      e.preventDefault(); // Stops the page from reloading!
    
      try {
        const {
          error,
          paymentIntent: { status }
        } = await stripe.confirmCardPayment(paymentIntent.client_secret);
    
        if (error) throw new Error(error.message);
    
        if (status === "succeeded") {
          alert('Payment made!')
        }
      } catch (err) {
        alert(err.message);
      }
    };
    
    우리의 지불 의도는 페이지를 불러오기 전에 서버에서 만든 것이기 때문에 이 예에서 우리는 사용자의 상하문이나 저장된 지불 방법이 없기 때문에 클라이언트에 하나를 만들고 두 번째 매개 변수에서 confirmCardPayment으로 보내야 한다.
    이것이 바로 CardElement 부품의 용무지이다.Stripe는 만기일, CVV, 우편 번호를 포함한 완전히 안전한 베이킹 신용카드 입력을 제공합니다.
    우리는 먼저 폼을 제출하기 위해 <CardElement /><button /> 구성 요소를 추가합니다.만약 button의 약속이 아직 해결되지 않았다면, stripe을 사용하지 않겠습니다.
    return (
      <form onSubmit={handleSubmit}>
        <CardElement />
    
        <button type="submit" disabled={!stripe}>
          Pay now
        </button>
      </form>
    );
    
    현재 http://localhost:3000/checkout에서 결제 페이지를 새로 고치면 다음과 같은 내용을 볼 수 있습니다.

    현재, 우리가 Pay now을 눌렀을 때, 테이프 측은 어떠한 지불 방식 데이터도 우리의 지불 의도에 부가되지 않았기 때문에 어떠한 일도 발생하지 않을 것이다.
    이제 handleSubmit을 업데이트하여 이 점을 실현합시다!
    우리는 elements.getElement을 사용하여 CardElement을 불러와 페이지의 카드 입력을 인용할 수 있습니다.
    const {
      error,
      paymentIntent: { status }
    } = await stripe.confirmCardPayment(paymentIntent.client_secret, {
      payment_method: {
        card: elements.getElement(CardElement)
      }
    });
    
    축하우리는 현재 기능이 완비된 지불 형식을 가지고 있다.🎉🎉🎉
    테스트 카드로 해봐.4242 4242 4242 4242은 SCA 문제를 해결할 필요가 없습니다.

    지금 우리는 아직 끝나지 않았다...페이지를 새로 고치고 지불을 시도하면 실패할 것입니다.이것은 우리가 쿠키에 저장된 paymentIntentId을 중복 사용했기 때문이라는 점이 이미 증명되었다.

    정리하다


    우리는 해야 할 일이 몇 가지 있다.
  • 결제 시 paymentIntentId 쿠키 삭제
  • 성공 메시지 보이기, 지불서
  • 대신
  • 오류 표시
  • 결제 완료 시 paymentIntentId 쿠키 제거

    components/CheckoutForm.js 내부에서 destroyCookie에서 nookes을 가져옵니다.
    // ...
    import { destroyCookie } from "nookies";
    
    현재 handleSubmit 함수에서 statussucceeded인지 확인합니다.여기에서 우리는 destroyCookie으로 전화를 걸어야 한다.
    // ..
    if (status === "succeeded") {
      destroyCookie(null, "paymentIntentId");
    }
    

    성공 / 오류 메시지


    이제 useState에서 react을 가져오고 두 가지 서로 다른 유형의 상태를 위해 갈고리를 호출합니다.
  • checkoutError
  • checkoutSuccess
  • const CheckoutForm = ({ paymentIntent }) => {
    // ...
    
    const [checkoutError, setCheckoutError] = useState();
    const [checkoutSuccess, setCheckoutSuccess] = useState();
    
    현재 handleSubmitsetCheckoutSuccess을 추가하고 성공적으로 지불할 때 true을 전달하며 setCheckoutError(err.message)블록에 catch을 전달합니다.
    try {
      // ...
    
      if (status === "succeeded") {
        setCheckoutSuccess(true);
        destroyCookie(null, "paymentIntentId");
      }
    } catch (err) {
      alert(err.message);
      setCheckoutError(err.message);
    }
    
    그리고 return의 표를 보여주기 전에 checkoutSuccess이 진실이라면 성공적인 단락을 되돌려줍니다.
    if (checkoutSuccess) return <p>Payment successful!</p>;
    
    마지막으로 <form>의 어딘가에 다음과 같은 내용을 추가한다.
    {checkoutError && <span style={{ color: "red" }}>{checkoutError}</span>}
    
    해냈어!

    Stripe Dashboard를 확인하면 성공적인 결제 의도도 볼 수 있습니다!


    최종 페이지 / 체크아웃.회사 명


    import React from "react";
    import Stripe from "stripe";
    import { parseCookies, setCookie } from "nookies";
    import { loadStripe } from "@stripe/stripe-js";
    import { Elements } from "@stripe/react-stripe-js";
    
    import CheckoutForm from "../components/CheckoutForm";
    
    const stripePromise = loadStripe("STRIPE_PUBLISHABLE_KEY");
    
    export const getServerSideProps = async ctx => {
      const stripe = new Stripe("STRIPE_SECRET_KEY");
    
      let paymentIntent;
    
      const { paymentIntentId } = await parseCookies(ctx);
    
      if (paymentIntentId) {
        paymentIntent = await stripe.paymentIntents.retrieve(paymentIntentId);
    
        return {
          props: {
            paymentIntent
          }
        };
      }
    
      paymentIntent = await stripe.paymentIntents.create({
        amount: 1000,
        currency: "gbp"
      });
    
      setCookie(ctx, "paymentIntentId", paymentIntent.id);
    
      return {
        props: {
          paymentIntent
        }
      };
    };
    
    const CheckoutPage = ({ paymentIntent }) => (
      <Elements stripe={stripePromise}>
        <CheckoutForm paymentIntent={paymentIntent} />
      </Elements>
    );
    
    export default CheckoutPage;
    

    최종 검사표.회사 명


    import React, { useState } from "react";
    import { CardElement, useStripe, useElements } from "@stripe/react-stripe-js";
    import { destroyCookie } from "nookies";
    
    const CheckoutForm = ({ paymentIntent }) => {
      const stripe = useStripe();
      const elements = useElements();
      const [checkoutError, setCheckoutError] = useState();
      const [checkoutSuccess, setCheckoutSuccess] = useState();
    
      const handleSubmit = async e => {
        e.preventDefault();
    
        try {
          const {
            error,
            paymentIntent: { status }
          } = await stripe.confirmCardPayment(paymentIntent.client_secret, {
            payment_method: {
              card: elements.getElement(CardElement)
            }
          });
    
          if (error) throw new Error(error.message);
    
          if (status === "succeeded") {
            setCheckoutSuccess(true);
            destroyCookie(null, "paymentIntentId");
          }
        } catch (err) {
          alert(err.message);
          setCheckoutError(err.message);
        }
      };
    
      if (checkoutSuccess) return <p>Payment successful!</p>;
    
      return (
        <form onSubmit={handleSubmit}>
          <CardElement />
    
          <button type="submit" disabled={!stripe}>
            Pay now
          </button>
    
          {checkoutError && <span style={{ color: "red" }}>{checkoutError}</span>}
        </form>
      );
    };
    
    export default CheckoutForm;
    
  • Get the code
  • 좋은 웹페이지 즐겨찾기