ラベル Stripe の投稿を表示しています。 すべての投稿を表示
ラベル Stripe の投稿を表示しています。 すべての投稿を表示

2023年8月24日木曜日

StripeのPaymentIntentsを使ったカード決済をAPEXアプリケーションに実装する

Stripeによる決済の実装は、以前にノーコードについては紹介したことがあります。こちらの記事になります。今回はPaymentIntentsを使ってカード決済を実装してみます。

Stripeの以下のドキュメントの記述にそって、Oracle APEXに合わせた実装を行います。

支払いページを作成する

Payment Intentの作成には、以下のREST APIを呼び出します。

カード番号の入力フォームはPayment Elementとして説明されています。

作成したアプリケーションは以下のように動作します。


最後にREST APIを呼び出してPayment Intentを表示しています。実際に決済の成功や失敗を確認するにはWebhookを実装するのが一般的だと思いますが、本記事ではWebhookの作成は取り扱っていません。通常Webhookは、APEXのアプリケーションではなく、ORDSのRESTサービスとして実装します。

以下より実装について説明します。

アプリケーション作成ウィザードを起動し、空のアプリケーションを作成します。名前Stripeとします。

アプリケーションの作成をクリックします。


アプリケーション定義置換文字列として、公開可能キーAPIのエンドポイントを設定します。

パブリックキーは置換文字列STRIPE_PUBLISHABLE_KEY置換値としてpk_test_で始まる(テスト用の)公開可能キーを設定します。

APIのエンドポイント置換文字列としてSTRIPE_ENDPOINT置換値としてhttps://api.stripe.comを設定します。


ワークスペース・ユーティリティWeb資格証明を開きます。


Stripeが提供するREST APIに使用するWeb資格証明は、以下の情報より作成します。

StripeのAPIは、ベアラーとしてシークレットキーを渡すことで認証できます。認証タイプHTTPヘッダーを選択し、資格証明名Authorization資格証明シークレットとして、文字列Bearerで始めて空白で区切り、シークレットキーの値を設定します。

Bearer シークレットキー

Web資格証明の名前Stripe CRED静的IDSTRIPE_CREDとして、Web資格証明を作成します。URLに対して有効https://api.stripe.comを設定します。

以上で作成をクリックします。


Web資格証明としてStripe CRED(静的IDはSTRIPE_CRED)が作成されました。


Stripeによるカード情報入力フォームを表示するページを作成します。

ページの作成をクリックします。


空白ページを選択します。


ページ番号(ページ・アイテム名に現れるため2とします)、名前Payページ・モードとしてドロワーを選択します。

ページの作成をクリックします。


ページPayが作成されました。

ホーム・ページでは決済金額を入力し、確定ボタンを押します。確定ボタンを押すとStripeが提供するカード情報を入力するフォームを実装したドロワーが開き、そこで決済を実行します。決済を実行すると、ドロワーが閉じます。


ページ・デザイナホーム・ページを開きます。

金額を入力するページ・アイテムP1_AMOUNTを作成します。

タイプ数値フィールドラベルAmountとします。


決済金額を確定するボタンCONFIRMを作成します。

ラベルConfirm外観ホットオンテンプレート・オプションWidthとしてStretchを選択します。動作アクションはデフォルトのページの送信から変更しません。


作成したPayment Intent IDを保持するページ・アイテムP1_PAYMENT_INTENT_IDClient Secretを保持するページ・アイテムP1_CLIENT_SECRETを作成します。双方ともタイプ非表示です。

Payment Intent IDはPayment Intentを表示する際に使用し、決済の確定では使用しません。APIリファレンスには、シークレットキーとPayment Intent IDを組み合わせてPayment Intentを取得する、または、公開可能キーとClient Secretを組み合わせてPayment Intentを取得する2通りの手順があるとのことです。Client Secretは決済の確定に使用します。

セッション・ステートストレージとしてセッションごと(永続)を選択します。決済の確定はPL/SQLで実行します。その際にページ・アイテムに設定されたPayment Intent IDは、ページ遷移の後でも値を維持するようにします。


Payment Intentを表示するリージョンを作成します。

識別タイトルPayment Intentタイプとして動的コンテンツを選択します。

ソースのCLOBを返すPL/SQLファンクション本体として以下を記述します。

ページ・アイテムP1_PAYMENT_INTENT_IDはセッション・ステートとして保持されているため、送信するページ・アイテムへの設定は不要です。


このリージョンをリフレッシュするボタンREFRESHを作成します。

ラベルはRefresh動作アクションとして動的アクションで定義を選択します。


ボタンREFRESH動的アクションを作成します。

識別名前onClick REFRESHタイミングイベントはボタンのデフォルトであるクリックです。


TRUEアクションとしてリフレッシュを選択します。影響を受ける要素選択タイプリージョンリージョンとしてPayment Intentを選択します。


このページを初期化するボタンCLEARを作成します。

ラベルClear動作アクションページの送信です。レイアウト新規行の開始オフにし、ボタンREFRESHの右隣に配置します。


プロセス・ビューを開き、ボタンを押した時に実行されるプロセスを作成します。

ボタンCONFIRMを押した時にPayment Intentを作成します。

プロセスの識別名前Create Payment Intentタイプとしてコードを実行を選択します。ソースPL/SQLコードとして以下を記述します。Payment Intentを作成するための最低限の処理です。


サーバー側の条件ボタン押下時としてCONFIRMを設定します。


ページを初期化するプロセスを作成します。

識別名前Clear Session Stateタイプセッション・ステートのクリア設定タイプとしてClear all Items on the Current Pageを選択します。

サーバー側の条件ボタン押下時としてCLEARを設定します。


ブランチを作成しプロセスの後に実行するように配置します。

識別名前Open Drawer動作タイプとしてページまたはURL(リダイレクト)を選択します。

サーバー側の条件ボタン押下時としてCONFIRMを設定します。


ターゲットは、タイプこのアプリケーションのページページです。アイテムの設定として、ページ・アイテムP2_CLIENT_SECRET&P1_CLIENT_SECRET.の値が渡るようにします。


以上で、ボタンをCONFIRMをクリックするとPayment Intentが作成され、そのClient Secretを(ページ・アイテムP2_CLIENT_SECRETへの)引数としてドロワーが開くようになります。

ページ・デザイナでページPayを開きます。

ページ・プロパティJavaScriptファイルURLとして、Stripeが提供しているJavaScriptライブラリを指定します。

https://js.stripe.com/v3/

ファンクションおよびグローバル変数の宣言に以下を記述します。

カード情報の入力フォームを生成しています。


クレジットカード情報を入力するフォームを生成するリージョンを作成します。

Content Bodyの直下にタイプ静的コンテンツのリージョンを作成します。

識別タイトルpayment-form、余計な装飾を省くため外観テンプレートとしてBlank with Attributes (No Grid)を選択します。詳細静的IDとしてpayment-formを設定します。このリージョンは実施的に以下のDIV要素を生成します。

<div id="payment-form">....</div>

Stripeのチュートリアルではidがpayment-formの要素はFORMです。Oracle APEXが生成したページにFORM要素がすでに含まれているためか、<form id="payment-form">では動作しません。そのため、代わりにDIV要素を作成しています。


リージョンpayment-formClient Secretを保持するページ・アイテムを作成します。

識別名前P2_CLIENT_SECRETタイプとして非表示を選択します。レイアウトリージョンとしてpayment-formを選択します。セッション・ステートストレージリクエストごと(メモリーのみ)とします。


クレジット・カードの所有者を入力するページ・アイテムを作成します。

識別名前P2_HOLDER_NAMEタイプテキスト・フィールドラベルHolder Nameとします。レイアウトリージョンとしてpayment-formを選択します。


リージョンpayment-formの子リージョンを作成します。

識別タイトルcard-elementタイプ静的コンテンツです。レイアウト親リージョンとしてpayment-formを指定します。このリージョンも余計な装飾を省くため、外観テンプレートとしてBlank with Attributes (No Grid)を選びます。詳細静的IDとしてcard-elementを設定します。


上にあるカードの所有者を入力するページ・アイテムと下にあるボタンが、カード情報を入力するリージョンに近過ぎたため、テンプレート・オプションTop MarginBottom MarginLargeに変更しています。


エラーを表示するリージョンを作成します。

識別タイトルcard-errorsタイプ静的コンテンツです。レイアウト親リージョンとしてpayment-formを指定します。このリージョンも余計な装飾を省くため、外観テンプレートとしてBlank with Attributes (No Grid)を選びます。詳細静的IDとしてcard-errorsを設定します。


決済を確定するボタンPAYを作成します。

ラベルPayレイアウトリージョンとしてpayment-form外観ホットオンにし、テンプレート・オプションWidthStretchを選択します。動作アクションとして動的アクションで定義を選択します。


ボタンPAYに動的アクションを作成します。

識別名前onClick PAYとします。タイミングイベントはボタンのデフォルトであるクリックです。


TRUEアクションとしてJavaScriptコードの実行を選択し、設定コードに以下を記述します。

カード決済が確定するとドロワーを閉じます。


以上でStripeのPayment Intentを使ったの決済サービスの実装は完了です。アプリケーションを実行すると、この記事の先頭のGIF動画のように動作します。

Oracle APEXのアプリケーション作成の参考になれば幸いです。


2023年5月19日金曜日

Autonomous DatabaseのStripe Viewにアクセスする

 Autonomous Databaseでは、Stripeに登録された顧客や製品などを一覧するビューが提供されています。

https://docs.oracle.com/en/cloud/paas/autonomous-database/adbsa/stripe-autonomous-database.html

以前にStripeを使う記事を書いたことがありStripeのアカウントが作成済みだったため、動作を確認してみました。

Stripeには以下の2つの商品が登録されています。


商品を一覧するビューSTRIPE_PRODUCTSを、対話モード・レポートで表示してみました。Stripeに登録されている商品がリストされています。


以下より、実施した作業について紹介します。

Oracle APEXのワークスペース・スキーマはWKSP_APEXDEVとします。ワークスペース・スキーマが異なる場合は、使用しているワークスペース・スキーマの名前に置き換えてください。

マニュアルの手順に従って作業を行います。

最初にAPEXのワークスペース・スキーマにネットワークACLを追加して、Stripeへのアクセスを許可します。principal_nameにワークスペース・スキーマWKSP_APEXDEVを指定します。
BEGIN
  DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
         host => 'stripe.com',
         ace  => xs$ace_type(privilege_list => xs$name_list('http'),
                             principal_name => 'WKSP_APEXDEV',
                             principal_type => xs_acl.ptype_db)
   );
END;
/
管理者ユーザーADMINでデータベース・アクションに接続し、SQLワークシートより実行します。


今回の例ではビューSTRIPE_PRODUCTSにアクセスします。APEXのワークスペース・スキーマに、ビューSTRIPE_PRODUCTSへの読み込み権限を与えます。

GRANT READ on STRIPE_PRODUCTS to WKSP_APEXDEV;


Autonomous Databaseでは、STRIPE_ACCOUNTSSTRIPE_COUPONSSTRIPE_CUSTOMERSSTRIPE_INVOICESSTRIPE_PLANSSTRIPE_PRODUCTSSTRIPE_SUBSCRIPTIONSといったビューが提供されています。READ権限は、これらのビューそれぞれに付与する必要があります。

管理者ユーザーADMINでの作業は完了です。

アプリケーション作成ウィザードを起動し、空のアプリケーションを作成します。名前Stripe Productsとします。


アプリケーションが作成されたら、ページ・デザイナホーム・ページを開きます。

対話モード・レポートのリージョンを作成します。

ソースの表名として、STRIPE_PRODUCTSを設定します。


以上でアプケーションを実行します。

クリデンシャルにアクセスができない、といったエラーが発生します。

ORA-20004: Credential "ORDS_PLSQL_GATEWAY"."STRIPE$CRED" does not exist


マニュアルによると、credential_nameSTRIPE$CREDであれば、デフォルトのクリデンシャルとして使用されると記述されています。これは、管理者ユーザーADMINに限定されているようです。ワークスペース・スキーマのデフォルト・クリデンシャルの指定ではスキーマ名による修飾が必須です。

ワークスペース・スキーマWKSP_APEXDEVに、Stripeへのアクセスで使用するクリデンシャルMY_STRIPE_CREDを作成します。

引数usernameStripeのユーザ名(通常メールアドレス)、passwordには、シークレットキーを指定します。


BEGIN
    DBMS_CLOUD.CREATE_CREDENTIAL(
        credential_name => 'MY_STRIPE_CRED',
        username        => 'Stripeのユーザー名',
        password        => 'シークレットキー' );
END;
/

作成されたクリデンシャルを、ビューUSER_CREDENTIALSより確認します。

select * from user_credentials where credential_name = 'MY_STRIPE_CRED';


クリデンシャルMY_STRIPE_CREDを、APEXアプリケーションが参照するようにします。

アプリケーション定義セキュリティデータベース・セッション初期化PL/SQLコードに以下を記述します。
begin
    execute immediate 'alter session set default_credential = ''WKSP_APEXDEV.MY_STRIPE_CRED''';
end;


以上で記事の先頭にあるように、対話モード・レポートにStripeに登録されている商品が一覧されます。

簡単なアプリケーションですが、今回作成したアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/stripe-products.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。

2022年8月23日火曜日

Stripeを使ってみる

 以前から気になっていたStripeをAPEXアプリケーションから呼び出して支払いを行ってみました。参考にした手順はOracle ACEであるLino SchildeさんのOracle APEX and Stripe v3 integration - part 1です。この記事にはpart2part3と後続の記事もあるのですが、今の所、それらは難しくて手に負えません。

Oracle CloudのAlways FreeのAutonomous Transaction Processingに、APEXアプリケーションを作成しています。

作業を実施しているのは2022年8月23日です。APEXのバージョンは22.1、その他のスクリーンショットなどは、この時点での情報になります。

以下より実施した手順を記述します。


Stripeのテスト環境を構成する


最初にStripeのダッシュボードにアクセスし、ユーザ登録を行います。

https://dashboard.stripe.com/login


Stripeアカウントの作成画面に移ります。メール氏名パスワードを入力し、アカウントを作成をクリックします。国について、ヘルプには「ビジネスが設立された国または地域を選択してください。個人の場合は、ビジネスを行っている国を選択してください。」と説明されています。この記事を読んでいる方であれば、日本を選択すると思います。


メールに指定したアドレスに、確認のためのメールが届きます。メールアドレスを確認をクリックします。


メールアドレスの確認が完了すると、Stripeのテスト環境にアクセスできるようになります。

本当に支払いを受け付ける場合は受け取り設定を行う必要があるようですが、今回はStripeとの連携テストを行うだけなので、テスト環境で作業を進めます。

Stripeのダッシュボードのホームを開き、開発者向け公開可能キーの位置を確認します。後でAPEXアプリケーションに記述するJavaScriptのコードに埋め込みます。


購入のテストに使用する商品を登録します。

商品タブを開き、商品を追加をクリックします。


商品が登録できていればよいので、商品情報の設定は自由です。今回の例では、商品詳細名前として入浴料説明北海道の温泉としています。画像も適当に貼り付けています。

料金情報料金体系モデルとして標準の料金体系価格500円にしました。支払い一括です。

以上の設定を行い、商品の保存をクリックします。


テスト環境ですが、商品の購入が可能になります。APEX側から支払いリクエストを発行する際に、料金API IDが引数になります。APEXアプリケーションで使用するので、この値を覚えておきます。


 今回はStripeのCheckoutクライアント側のみの組み込みを行います。そのため、設定CheckoutとPayment Linksを開き、クライアント側のみの組み込みを有効にするをクリックします。商品IDが公開されます、と確認を求められるので、許可をクリックします。

https://dashboard.stripe.com/settings/checkout


Stripe側の準備は以上で完了です。

公開可能キーと商品のAPI IDを使って、この商品を購入するAPEXアプリケーションを作成します。


APEXアプリケーションを作成する



アプリケーション作成ウィザードを起動します。

ホーム・ページはそのままにし、空白のページ2つ追加します。ページ名としてsuccess、もう一つはerrorとします。

以上でアプリケーションの作成をクリックします。


アプリケーションが作成されます。

アプリケーションはすべてホーム・ページに実装します。success、errorのページはStripeでの支払いが成功または失敗したときに呼び出されるページで、今回は何も実装しません。


 ページ・デザイナにてホーム・ページを開きます。

デフォルトで作成されているページ・ナビゲーション削除します。


 ページ・アイテムP1_PRODUCTを作成します。商品API IDを指定します。

識別名前P1_PRODUCTタイプテキスト・フィールドとします。ラベルProductとします。


ページ・アイテムP1_QUANTITYを作成します。商品個数を指定します。

識別名前P1_QUANTITYタイプ数値フィールドとします。ラベルQuantityレイアウト新規行の開始OFFにし、Productの右にページ・アイテムを配置します。


Stripeに支払いを要求するボタンB_STRIPE_PAYを作成します。

識別ボタン名B_STRIPE_PAYラベルStripe Payとします。レイアウト新規行の開始OFFとし、Quantityの右にボタンを配置します。詳細カスタム属性として、以下を記述します。

data-action="#action$stripe-payment"

Stripeを呼び出す処理は、APEXアクションのstripe-paymentとして実装します。


Stripeの呼び出しを実装します。

ページ・プロパティJavaScriptファイルURLとして、以下を記述します。

https://js.stripe.com/v3/

StripeのJavaScriptライブラリv3を読み込んでいます。


ファンクションおよびグローバル変数の宣言として、以下を記述します。

Stripeオブジェクトを作成するにあたって、pk_で始まる公開可能キーをコンストラクタに与えます。

apex_pathはAPEXを実行している環境に依存して形式は変わります。アプリケーションに作成しているsuccessページやerrorページを開き、URLを確認した上でapex_pathを設定します。customerEmailには、商品を購入する人のメール・アドレスを設定します。
var stripe = Stripe('pk_公開可能キーの貼り付け');
var apex_path = 'https://ホスト名/ords/r/ワークスペース名/';
var successUrl = apex_path + '/stripe-payment/success?session=' + apex.env.APP_SESSION;
var cancelUrl =  apex_path + '/stripe-payment/error?session=' + apex.env.APP_SESSION;
var customerEmail = '電子メール・アドレス';

ページ・ロードに時に実行に、以下を記述します。APEXアクションで実装していると、カード・リージョンやレポートからの呼び出しの対応が容易です。



Stripeの画面に遷移する際、APEXで保存されていない変更について警告のポップアップが表示されます。それを抑止するためにページ・プロパティのナビゲーション保存されていない変更の警告OFFにします。


以上でアプリケーションは完成です。

アプリケーションを実行して、動作を確認します。

Productに商品のAPI IDを入力し、Quantityに1以上の数値を入力します。その後、ボタンStripe Payをクリックします。


Stripeの支払い画面が開きます。テストカードの情報は、Stripe Docのテストに一覧されています。

https://stripe.com/docs/testing

カード情報を入力し、支払うをクリックします。


支払いに成功すると、Successページが表示されます。


Stripeのダッシュボード支払いを開くと、支払い履歴を確認することができます。

以上で、APEXアプリケーションからStripeによる支払いができることを確認しました。

基本的な実装ですが、Stripeのダッシュボードのホームに書かれているように「何から始めればよいのかわからない場合」というのは多いように思います。


クライアント側のみの組み込みであれば、クレジット・カード情報といったセンシティブなデータをAPEX側で保持しないので、比較的導入しやすいように思います。

今回の記事は以上になります。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/basic-stripe-integration.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。

追記

その他のPayment Gatewayとの連携としては、以下の紹介記事があります。

PayPal(USA)は、Jon Dixsonさんによる記事
Receiving Payments from Oracle APEX with PayPal.
https://blog.cloudnueva.com/apex-paypal
Razorpay(主にIndia)は、Karkuvelraja Thangamariappanさんによる記事
Mollie(主にEU)は、Alan Arentsenによるセミナー資料と動画
Where it all comes together, doing secure payments with APEX.