1. 概要

Stripe は、企業や個人がインターネットを介して支払いを受け取ることを可能にするクラウドベースのサービスであり、クライアント側ライブラリ(JavaScriptとネイティブモバイル)とサーバー側ライブラリ(Java)の両方を提供します、Ruby、Node.jsなど)。

Stripeは、支払いの受け取りの複雑さを軽減する抽象化レイヤーを提供します。 その結果、クレジットカードの詳細を直接処理する必要はありません。代わりに、請求の承認を象徴するトークンを処理します。

このチュートリアルでは、ユーザーがクレジットカードを入力できるようにするサンプルのSpring Bootプロジェクトを作成し、後で Stripe API forJavaを使用してカードに特定の金額を請求します。

2. 依存関係

プロジェクトでStripeAPI for Java を利用するには、対応する依存関係をpom.xmlに追加します。

<dependency>
    <groupId>com.stripe</groupId>
    <artifactId>stripe-java</artifactId>
    <version>4.2.0</version>
</dependency>

の最新バージョンはMavenCentralリポジトリにあります。

サンプルプロジェクトでは、spring-boot-starter-parentを活用します。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.1</version>
</parent>

また、 Lombok を使用してボイラープレートコードを削減し、Thymeleafが動的Webページを配信するためのテンプレートエンジンになります。

これらのライブラリのバージョンを管理するためにspring-boot-starter-parent を使用しているため、pom.xmlにそれらのバージョンを含める必要はありません。

<dependency>
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

NetBeansを使用している場合は、バージョン1.16.16 でLombokを明示的に使用することをお勧めします。これは、Spring Boot 1.5.2で提供されるバージョンのLombokのバグにより、NetBeansが大量に生成するためです。エラーの。

3. APIキー

Stripeと通信してクレジットカードの請求を実行する前に、 Stripeアカウントを登録し、シークレット/パブリックStripeAPIキーを取得する必要があります。

アカウントを確認した後、ログインしてStripeダッシュボードにアクセスします。 次に、左側のメニューで[APIキー]を選択します。

シークレット/パブリックキーのペアが2つあります。1つはテスト用、もう1つはライブ用です。 後でこれらのキーを使用できるように、このタブを開いたままにしておきましょう。

4. 一般的なフロー

クレジットカードの請求は、フロントエンド(ブラウザで実行)、バックエンド(Spring Bootアプリケーション)、およびStripeを含む5つの簡単なステップで行われます。

  1. ユーザーがチェックアウトページに移動し、[カードで支払う]をクリックします。
  2. ユーザーには、クレジットカードの詳細を入力するStripeCheckoutオーバーレイダイアログが表示されます。
  3. ユーザーは「支払い 」これは:
    • クレジットカードをStripeに送信します
    • 既存のフォームに追加される応答でトークンを取得します
    • 金額、公開APIキー、メールアドレス、トークンを記載したフォームをバックエンドに送信します

  4. バックエンドは、トークン、金額、および秘密のAPIキーを使用してStripeに連絡します。
  5. バックエンドはStripe応答をチェックし、操作のフィードバックをユーザーに提供します。

次のセクションでは、各ステップについて詳しく説明します。

5. チェックアウトフォーム

Stripe Checkout は、カスタマイズ可能、モバイル対応、ローカライズ可能なウィジェットで、クレジットカードの詳細を紹介するフォームをレンダリングします。 「checkout.js」を含めて構成することにより、次の責任を負います。

  • 「カードで支払う」ボタンのレンダリング
  • 支払いオーバーレイダイアログのレンダリング([カードで支払う]をクリックするとトリガーされます)
  • クレジットカードの検証
  • 「Rememberme」機能(カードを携帯電話番号に関連付ける)
  • クレジットカードをStripeに送信し、同封のフォームのトークンに置き換えます([支払い]をクリックするとトリガーされます 」)

Stripe Checkoutによって提供されるよりもチェックアウトフォームをより細かく制御する必要がある場合は、 StripeElementsを使用できます。

次に、フォームを作成するコントローラーを分析し、次にフォーム自体を分析します。

5.1. コントローラ

まず、コントローラーを作成してチェックアウトフォームに必要な情報をモデルに準備します

まず、Stripeダッシュボードから公開鍵のテストバージョンをコピーし、それを使用してSTRIPE_PUBLIC_KEYを環境変数として定義する必要があります。 次に、この値をstrippePublicKeyフィールドで使用します。

ここでは、デモンストレーションの目的で currencyamount (セントで表される)も手動で設定していますが、実際のアプリケーションでは、使用できる商品/販売IDを設定する場合があります実際の値を取得します。

次に、チェックアウトフォームを保持するチェックアウトビューにディスパッチします。

@Controller
public class CheckoutController {

    @Value("${STRIPE_PUBLIC_KEY}")
    private String stripePublicKey;

    @RequestMapping("/checkout")
    public String checkout(Model model) {
        model.addAttribute("amount", 50 * 100); // in cents
        model.addAttribute("stripePublicKey", stripePublicKey);
        model.addAttribute("currency", ChargeRequest.Currency.EUR);
        return "checkout";
    }
}

Stripe APIキーに関しては、アプリケーションごとの環境変数として定義できます(テストと 住む)。

パスワードや機密情報の場合と同様に、バージョン管理システムに秘密鍵を入れないようにするのが最善です。

5.2. 形

「カードで支払う」ボタンとチェックアウトダイアログは、データ属性で正しく構成されたスクリプトを内部に含むフォームを追加することで含まれます。

<form action='/charge' method='POST' id='checkout-form'>
    <input type='hidden' th:value='${amount}' name='amount' />
    <label>Price:<span th:text='${amount/100}' /></label>
    <!-- NOTE: data-key/data-amount/data-currency will be rendered by Thymeleaf -->
    <script
       src='https://checkout.stripe.com/checkout.js' 
       class='stripe-button'
       th:attr='data-key=${stripePublicKey}, 
         data-amount=${amount}, 
         data-currency=${currency}'
       data-name='Baeldung'
       data-description='Spring course checkout'
       data-image
         ='https://www.baeldung.com/wp-content/themes/baeldung/favicon/android-chrome-192x192.png'
       data-locale='auto'
       data-zip-code='false'>
   </script>
</form>

checkout.js」スクリプトは、送信の直前にStripeへのリクエストを自動的にトリガーし、StripeトークンとStripeユーザーの電子メールを非表示フィールド「strippeToken」と「 strippeEmail」。

これらは、他のフォームフィールドとともにバックエンドに送信されます。 スクリプトデータ属性は送信されません。

Thymeleafを使用して、属性「 data-key 」、「 data-amount 」、および「data-currency」をレンダリングします。

金額(「 data-amount 」)は、表示目的でのみ使用されます(「 data-currency 」とともに)。 その単位は使用通貨のセントであるため、100で割って表示します。

Stripe公開鍵は、ユーザーが支払いを要求した後にStripeに渡されます。 ここでは秘密鍵を使用しないでください。これはブラウザに送信されます。

6. 充電操作

サーバー側の処理では、チェックアウトフォームで使用されるPOSTリクエストハンドラーを定義する必要があります。 充電操作に必要なクラスを見てみましょう。

6.1. ChargeRequestエンティティ

課金操作中にビジネスエンティティとして使用するChargeRequestPOJOを定義しましょう。

@Data
public class ChargeRequest {

    public enum Currency {
        EUR, USD;
    }
    private String description;
    private int amount;
    private Currency currency;
    private String stripeEmail;
    private String stripeToken;
}

6.2. サービス

StripeService クラスをに記述して、実際の充電操作をStripeに伝達しましょう。

@Service
public class StripeService {

    @Value("${STRIPE_SECRET_KEY}")
    private String secretKey;
    
    @PostConstruct
    public void init() {
        Stripe.apiKey = secretKey;
    }
    public Charge charge(ChargeRequest chargeRequest) 
      throws AuthenticationException, InvalidRequestException,
        APIConnectionException, CardException, APIException {
        Map<String, Object> chargeParams = new HashMap<>();
        chargeParams.put("amount", chargeRequest.getAmount());
        chargeParams.put("currency", chargeRequest.getCurrency());
        chargeParams.put("description", chargeRequest.getDescription());
        chargeParams.put("source", chargeRequest.getStripeToken());
        return Charge.create(chargeParams);
    }
}

CheckoutController に示されているように、 secretKeyフィールドは、StripeダッシュボードからコピーしたSTRIPE_SECRET_KEY環境変数から入力されます。

サービスが初期化されると、このキーは後続のすべてのStripe操作で使用されます。

Stripeライブラリによって返されるオブジェクトは、 Charge操作を表し、操作IDなどの有用なデータが含まれています。

6.3. コントローラ

最後に、チェックアウトフォームからのPOSTリクエストを受信するコントローラーを作成し、StripeServiceを介してStripeに請求を送信しましょう。

ChargeRequest」パラメーターは、要求パラメーター「 amount 」、「 stripeEmail 」、および「strippeToken」で自動的に初期化されることに注意してください。フォームに含まれるもの:

@Controller
public class ChargeController {

    @Autowired
    private StripeService paymentsService;

    @PostMapping("/charge")
    public String charge(ChargeRequest chargeRequest, Model model)
      throws StripeException {
        chargeRequest.setDescription("Example charge");
        chargeRequest.setCurrency(Currency.EUR);
        Charge charge = paymentsService.charge(chargeRequest);
        model.addAttribute("id", charge.getId());
        model.addAttribute("status", charge.getStatus());
        model.addAttribute("chargeId", charge.getId());
        model.addAttribute("balance_transaction", charge.getBalanceTransaction());
        return "result";
    }

    @ExceptionHandler(StripeException.class)
    public String handleError(Model model, StripeException ex) {
        model.addAttribute("error", ex.getMessage());
        return "result";
    }
}

成功したら、ステータス、操作ID、請求ID、および残高トランザクションIDをモデルに追加して、後でユーザーに表示できるようにします(セクション7)。 これは、チャージオブジェクトの内容の一部を説明するために行われます。

ExceptionHandler は、充電操作中にスローされるタイプStripeExceptionの例外を処理します。

よりきめ細かいエラー処理が必要な場合は、 StripeException 、 CardException RateLimitException AuthenticationExceptionなど、StripeExceptionのサブクラスに個別のハンドラーを追加できます。

result」ビューは、充電操作の結果を表示します。

7. 結果を表示する

結果の表示に使用されるHTMLは、課金操作の結果を表示する基本的なThymeleafテンプレートです。 ユーザーは、充電操作が成功したかどうかに関係なく、ChargeControllerによってここに送信されます。

<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xmlns:th='http://www.thymeleaf.org'>
    <head>
        <title>Result</title>
    </head>
    <body>
        <h3 th:if='${error}' th:text='${error}' style='color: red;'></h3>
        <div th:unless='${error}'>
            <h3 style='color: green;'>Success!</h3>
            <div>Id.: <span th:text='${id}' /></div>
            <div>Status: <span th:text='${status}' /></div>
            <div>Charge id.: <span th:text='${chargeId}' /></div>
            <div>Balance transaction id.: <span th:text='${balance_transaction}' /></div>
        </div>
        <a href='/checkout.html'>Checkout again</a>
    </body>
</html>

成功すると、ユーザーには充電操作の詳細が表示されます。

エラーが発生すると、Stripeから返されるエラーメッセージがユーザーに表示されます。

8. 結論

このチュートリアルでは、StripeJavaAPIを使用してクレジットカードに請求する方法を示しました。 将来的には、サーバー側のコードを再利用してネイティブモバイルアプリを提供できるようになる可能性があります。

チャージフロー全体をテストするために、実際のクレジットカードを使用する必要はありません(テストモードでも)。 代わりに、Stripeテストカードを使用できます。

課金操作は、StripeJavaAPIによって提供される多くの可能性の1つです。 公式APIリファレンスは、一連の操作全体をガイドします。

このチュートリアルで使用されるサンプルコードは、GitHubプロジェクトにあります。