PaymentSheet
クラスを使用して、Stripe の構築済み支払い UI を Android アプリの決済フローに組み込みます。
購入画面で決済手段を直接表示することをご希望の場合 Stripe を設定する まず、Stripe アカウントが必要です。今すぐ登録 してください。
サーバー側 この接続方法では、Stripe API と通信するエンドポイントがサーバー上に必要です。サーバーから Stripe API にアクセスするには、Stripe の公式ライブラリーを使用します。
クライアント側 Stripe Android SDK はオープンソースであり、詳細なドキュメントが提供されています 。
SDK をインストールするには、app/build.gradle
ファイルの dependencies
ブロックに、stripe-android
を追加します。
apply plugin : 'com.android.application'
android { ... }
dependencies {
implementation 'com.stripe:stripe-android:20.47.4'
}
支払い方法を有効にする
決済手段の設定 を表示して、サポートする決済手段を有効にします。PaymentIntent を作成するには、少なくとも 1 つは決済手段を有効にする必要があります。
By default, Stripe enables cards and other prevalent payment methods that can help you reach more customers, but we recommend turning on additional payment methods that are relevant for your business and customers. See Payment method integration options for product and payment method support, and our pricing page for fees.
この接続方法では、以下の 3 つの Stripe API オブジェクトを使用します。
PaymentIntent : Stripe uses this to represent your intent to collect payment from a customer, tracking your charge attempts and payment state changes throughout the process.
(Optional) Customer : To set up a payment method for future payments, you must attach it to a Customer . Create a Customer object when your customer creates an account with your business. If your customer is making a payment as a guest, you can create a Customer object before payment and associate it with your own internal representation of the customer’s account later.
(オプション) Customer Ephemeral Key (顧客の一時キー): Customer オブジェクトの情報は機密情報であるため、アプリから直接取得することはできません。Ephemeral Key により、SDK に Customer への一時的なアクセス権が付与されます。
注 Customer にカードを保存したことがなく、リピート顧客に保存されたカードの再利用を許可しない場合は、実装で Customer オブジェクトおよび Customer Ephemeral Key オブジェクトを省略できます。
セキュリティ上の理由により、アプリでこれらのオブジェクトを作成することはできません。代わりに、サーバー側で以下を行うエンドポイントを追加します。
Customer を取得するか、新規作成する。 Customer の一時キーを作成する。 Creates a PaymentIntent with the amount , currency , and customer . You can also optionally include the automatic_payment_methods
parameter. Stripe enables its functionality by default in the latest version of the API. Returns the Payment Intent’s client secret , the Ephemeral Key’s secret
, the Customer’s id , and your publishable key to your app. 決済プロセス中に顧客に表示される決済手段は、PaymentIntent にも含まれています。Stripe にダッシュボードの設定から決済手段を取得するよう指定することも、手動でリストに表示することもできます。選択したオプションにかかわらず、顧客に表示される決済手段は、PaymentIntent で渡す通貨によって絞り込まれることにご注意ください。たとえば、PaymentIntent で eur
を渡し、ダッシュボードで OXXO が有効になっている場合、OXXO は eur
による決済に対応していないため、顧客に表示されません。
構築済みのシステムで、決済手段を提供するためにコードベースのオプションが必要になる場合を除き、自動化されたオプションを使用することをお勧めします。これは、Stripe が通貨、決済手段の制約、その他のパラメーターを評価して、対応可能な決済手段を決定するためです。自動化されたオプションでは、購入完了率の向上につながり、使用通貨と顧客の所在地に最適な決済手段が優先的に表示されます。
注 このエンドポイントの実行可能な実装内容を Glitch でテストします。
決済手段はダッシュボード で管理できます。Stripe は取引額、通貨、決済フローなどの要素に基づいて、適切な決済手段が返されるように処理します。PaymentIntent は、ダッシュボードで設定された決済手段を使用して作成されます。ダッシュボードを使用しない場合や、決済手段を手動で指定する場合は、payment_method_types
属性を使用して決済手段を一覧表示することができます。
curl https://api.stripe.com/v1/customers \
-u sk_test_4eC39HqLyjWDarjtT1zdp7dc
: \
-X "POST"
curl https://api.stripe.com/v1/ephemeral_keys \
-u sk_test_4eC39HqLyjWDarjtT1zdp7dc
: \
-H "Stripe-Version: 2024-06-20" \
-X "POST" \
-d "customer" = "{{CUSTOMER_ID}}" \
curl https://api.stripe.com/v1/payment_intents \
-u sk_test_4eC39HqLyjWDarjtT1zdp7dc
: \
-X "POST" \
-d "customer" = "{{CUSTOMER_ID}}" \
-d "amount" = 1099 \
-d "currency" = "eur" \
-d "automatic_payment_methods[enabled]" = true \
支払いの詳細を収集する 決済ページでは、モバイル決済 Element を表示する前に以下を実行する必要があります。
購入商品と合計金額を表示する Collect any required shipping information using the Address Element Stripe の UI を表示する決済ボタンを含める 決済アクティビティーの onCreate
内で、結果を処理するメソッドを渡して、PaymentSheet
インスタンスを初期化 します。
import androidx . compose . runtime . Composable
import com . stripe . android . paymentsheet . PaymentSheetResult
import com . stripe . android . paymentsheet . rememberPaymentSheet
@Composable
fun App ( ) {
val paymentSheet = rememberPaymentSheet ( :: onPaymentSheetResult )
}
private fun onPaymentSheetResult ( paymentSheetResult : PaymentSheetResult ) {
}
次に、前のステップで作成したエンドポイントから、PaymentIntent の client secret、一時キーの secret、Customer ID、公開可能キーを取得します。公開可能キーは PaymentConfiguration
を使用して設定し、その他は保存して、PaymentSheet を表示するときに使用します。
import androidx . compose . runtime . Composable
import androidx . compose . runtime . LaunchedEffect
import androidx . compose . runtime . getValue
import androidx . compose . runtime . mutableStateOf
import androidx . compose . runtime . remember
import androidx . compose . runtime . setValue
import androidx . compose . ui . platform . LocalContext
import com . github . kittinunf . fuel . httpPost
import com . github . kittinunf . fuel . json . responseJson
import com . stripe . android . PaymentConfiguration
import com . stripe . android . paymentsheet . PaymentSheet
import com . stripe . android . paymentsheet . PaymentSheetResult
import com . stripe . android . paymentsheet . rememberPaymentSheet
import com . github . kittinunf . result . Result
@Composable
fun App ( ) {
val paymentSheet = rememberPaymentSheet ( :: onPaymentSheetResult )
val context = LocalContext . current
var customerConfig by remember { mutableStateOf < PaymentSheet . CustomerConfiguration ? > ( null ) }
var paymentIntentClientSecret by remember { mutableStateOf < String ? > ( null ) }
LaunchedEffect ( context ) {
"Your backend endpoint/payment-sheet" . httpPost ( ) . responseJson { _ , _ , result ->
if ( result is Result . Success ) {
val responseJson = result . get ( ) . obj ( )
paymentIntentClientSecret = responseJson . getString ( "paymentIntent" )
customerConfig = PaymentSheet . CustomerConfiguration (
responseJson . getString ( "customer" ) ,
responseJson . getString ( "ephemeralKey" )
)
val publishableKey = responseJson . getString ( "publishableKey" )
PaymentConfiguration . init ( context , publishableKey )
}
}
}
}
private fun onPaymentSheetResult ( paymentSheetResult : PaymentSheetResult ) {
}
顧客が決済ボタンをタップしたら、presentWithPaymentIntent
を呼び出して支払い画面を表示します。顧客が支払いを完了すると、画面が閉じ、PaymentSheetResultCallback
が PaymentSheetResult
とともに呼び出されます。
import androidx . compose . material . Button
import androidx . compose . material . Text
import androidx . compose . runtime . Composable
import androidx . compose . runtime . LaunchedEffect
import androidx . compose . runtime . getValue
import androidx . compose . runtime . mutableStateOf
import androidx . compose . runtime . remember
import androidx . compose . runtime . setValue
import androidx . compose . ui . platform . LocalContext
import com . github . kittinunf . fuel . httpPost
import com . github . kittinunf . fuel . json . responseJson
import com . stripe . android . PaymentConfiguration
import com . stripe . android . paymentsheet . PaymentSheet
import com . stripe . android . paymentsheet . PaymentSheetResult
import com . stripe . android . paymentsheet . rememberPaymentSheet
import com . github . kittinunf . result . Result
@Composable
fun App ( ) {
val paymentSheet = rememberPaymentSheet ( :: onPaymentSheetResult )
val context = LocalContext . current
var customerConfig by remember { mutableStateOf < PaymentSheet . CustomerConfiguration ? > ( null ) }
var paymentIntentClientSecret by remember { mutableStateOf < String ? > ( null ) }
LaunchedEffect ( context ) {
"Your backend endpoint/payment-sheet" . httpPost ( ) . responseJson { _ , _ , result ->
if ( result is Result . Success ) {
val responseJson = result . get ( ) . obj ( )
paymentIntentClientSecret = responseJson . getString ( "paymentIntent" )
customerConfig = PaymentSheet . CustomerConfiguration (
responseJson . getString ( "customer" ) ,
responseJson . getString ( "ephemeralKey" )
)
val publishableKey = responseJson . getString ( "publishableKey" )
PaymentConfiguration . init ( context , publishableKey )
}
}
}
Button (
onClick = {
val currentConfig = customerConfig
val currentClientSecret = paymentIntentClientSecret
if ( currentConfig != null && currentClientSecret != null ) {
presentPaymentSheet ( paymentSheet , currentConfig , currentClientSecret )
}
}
) {
Text ( "Checkout" )
}
}
private fun presentPaymentSheet (
paymentSheet : PaymentSheet ,
customerConfig : PaymentSheet . CustomerConfiguration ,
paymentIntentClientSecret : String
) {
paymentSheet . presentWithPaymentIntent (
paymentIntentClientSecret ,
PaymentSheet . Configuration (
merchantDisplayName = "My merchant name" ,
customer = customerConfig ,
allowsDelayedPaymentMethods = true
)
)
}
private fun onPaymentSheetResult ( paymentSheetResult : PaymentSheetResult ) {
when ( paymentSheetResult ) {
is PaymentSheetResult . Canceled -> {
print ( "Canceled" )
}
is PaymentSheetResult . Failed -> {
print ( "Error: ${ paymentSheetResult . error } " )
}
is PaymentSheetResult . Completed -> {
print ( "Completed" )
}
}
}
allowsDelayedPaymentMethods
を true に設定すると、アメリカの銀行口座などの 遅延通知型 の決済手段を使用できます。これらの決済手段では、PaymentSheet
が完了した時点では最終的な支払いステータスが判明せず、後になって成功または失敗が確定します。このようなタイプの決済手段に対応する場合は、注文が確定済みであることを顧客に通知し、支払いが成功した場合にのみ注文のフルフィルメント (商品の発送など) を実行するようにします。
支払い後のイベントを処理する Stripe sends a payment_intent.succeeded event when the payment completes. Use the Dashboard webhook tool or follow the webhook guide to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow.
クライアントからのコールバックを待つのではなく、これらのイベントをリッスンします。クライアントでは、コールバックが実行される前に顧客がブラウザーのウィンドウを閉じたり、アプリを終了する場合、また悪意を持つクライアントがレスポンスを不正操作する場合もあります。非同期型のイベントをリッスンするよう組み込みを設定すると、単一の組み込みで複数の異なるタイプの決済手段 を受け付けることができます。
Payment Element を使用して支払いを回収する場合は、payment_intent.succeeded
イベントのほかにこれらのイベントを処理することをお勧めします。
イベント 説明 アクション payment_intent.succeeded 顧客が正常に支払いを完了したときに送信されます。 顧客に注文の確定を送信し、顧客の注文のフルフィルメント を実行します。 payment_intent.processing 顧客が正常に支払いを開始したが、支払いがまだ完了していない場合に送信されます。このイベントは、多くの場合、顧客が口座引き落としを開始するときに送信されます。その後、payment_intent.succeeded
イベント、また、失敗の場合は payment_intent.payment_failed
イベントが送信されます。 顧客に注文確認メールを送信し、支払いが保留中であることを示します。デジタル商品では、支払いの完了を待たずに注文のフルフィルメントを行うことが必要になる場合があります。 payment_intent.payment_failed 顧客が支払いを試みたが、支払いに失敗する場合に送信されます。 支払いが processing
から payment_failed
に変わった場合は、顧客に再度支払いを試すように促します。
組み込みをテストする
カード番号 シナリオ テスト方法 4242 4242 4242 4242 カード支払いは成功し、認証は必要とされません。 クレジットカード番号と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 4000 0025 0000 3155 カード支払いには認証 が必要です。 クレジットカード番号と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 4000 0000 0000 9995 カードは、insufficient_funds
などの拒否コードで拒否されます。 クレジットカード番号と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 6205 5000 0000 0000 004 UnionPay カードは、13 ~ 19 桁の可変長です。 クレジットカード番号と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。
実装内容をテストするためのその他の情報については、テスト をご覧ください。