連結アカウントが提供する商品またはサービスについて、顧客がプラットフォームと取引するときに「デスティネーション支払い」を作成し、連結アカウントに売上を即時に送金します。この支払いタイプの特徴は以下のとおりです。
プラットフォームのアカウントで支払いを作成します。 売上の一部または全額を、連結アカウントに送金するかどうかを決定します。 Stripe の手数料、返金、チャージバックは、お客様のアカウント残高から引き落とされます。 この支払いタイプは、住宅賃貸マーケットプレイスの Airbnb や、ライドシェアアプリの Lyft などのマーケットプレイスに最適です。
デスティネーション支払いは、プラットフォームと連結アカウントの両方が同じ国に所在する場合にのみサポートされます。国境を超える場合に対応するには、Payment Intent で on_behalf_of パラメーターを使用して連結アカウントに売上処理加盟店 を指定する必要があります。あるいは、その他の有効な海外送金 のシナリオをご確認ください。
注 Express ダッシュボードにアクセスできる連結アカウント、またはダッシュボードにアクセスできない連結アカウントには、デスティネーション支払いを使用することをお勧めします。
Integrate Stripe’s prebuilt payment UI into the checkout of your Android app with the PaymentSheet class.
まず、Stripe アカウントが必要です。今すぐ登録してください 。
サーバー側 この接続方法では、Stripe API と通信するエンドポイントがサーバー上に必要です。サーバーから Stripe API にアクセスするには、Stripe の公式ライブラリを使用します。
クライアント側 Stripe Android SDK はオープンソースであり、詳細なドキュメントが提供されています 。
To install the SDK, add stripe-android
to the dependencies
block of your app/build.gradle file:
plugins {
id ( "com.android.application" )
}
android { .. . }
dependencies {
implementation ( "com.stripe:stripe-android:21.12.0" )
implementation ( "com.stripe:financial-connections:21.12.0" )
}
Stripe の公開可能キー を使用して SDK を設定し、 Application
サブクラスなどで、Stripe API へのリクエストを実行できるようにします。
import com . stripe . android . PaymentConfiguration
class MyApp : Application ( ) {
override fun onCreate ( ) {
super . onCreate ( )
PaymentConfiguration . init (
applicationContext ,
"pk_test_TYooMQauvdEDq54NiTphI7jx"
)
}
}
注 Use your test keys while you test and develop, and your live mode keys when you publish your app.
この接続方法では、以下の 3 つの Stripe API オブジェクトを使用します。
PaymentIntent (支払いインテント) : Stripe はこれを使用して、顧客から支払いを回収する意図を示し、プロセス全体を通して支払いの試行と支払い状態の変化を追跡します。
(オプション) Customer (顧客) : 今後の支払いに備えて決済手段を設定するには、決済手段をCustomer に関連付ける必要があります。Customer オブジェクトは、顧客がビジネスでアカウントを作成するときに作成します。顧客がゲストとして支払いを行う場合は、支払いの前に Customer オブジェクトを作成し、後でこのオブジェクトを顧客のアカウントを表す内部表現に関連付けることができます。
(オプション) Customer Ephemeral Key (顧客の一時キー): Customer オブジェクトの情報は機密情報であるため、アプリから直接取得することはできません。Ephemeral Key により、SDK に Customer への一時的なアクセス権が付与されます。
注 Customer にカードを保存したことがなく、リピート顧客に保存されたカードの再利用を許可しない場合は、実装で Customer オブジェクトおよび Customer Ephemeral Key オブジェクトを省略できます。
セキュリティ上の理由により、アプリでこれらのオブジェクトを作成することはできません。代わりに、サーバー側で以下を行うエンドポイントを追加します。
Customer を取得するか、新規作成する。 Customer の一時キーを作成する。 amount 、currency 、customer 、 を指定して PaymentIntent を作成します。オプションで、automatic_ payment_ methods
パラメーターを含めることもできます。Stripe は、最新バージョンの API ではこの機能をデフォルトで有効にしています。PaymentIntent の client secret 、一時キーの secret
、顧客の id 、および貴社の公開可能キー をアプリに返します。 決済プロセス中に顧客に表示される支払い方法は、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_BQokikJOvBiI2HlWgH4olfQ2
: \
-X "POST"
curl https://api.stripe.com/v1/ephemeral_keys \
-u sk_test_BQokikJOvBiI2HlWgH4olfQ2
: \
-H "Stripe-Version: 2025-04-30.basil" \
-X "POST" \
-d "customer" = "{{CUSTOMER_ID}}" \
curl https://api.stripe.com/v1/payment_intents \
-u sk_test_BQokikJOvBiI2HlWgH4olfQ2
: \
-X "POST" \
-d "customer" = "{{CUSTOMER_ID}}" \
-d "amount" = 1099 \
-d "currency" = "eur" \
-d "automatic_payment_methods[enabled]" = true \
-d application_fee_amount = "123" \
-d "transfer_data[destination]" = \
決済ページでは、Mobile Payment Element を表示する前に以下を実行する必要があります。
決済アクティビティーの 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 (
id = responseJson . getString ( "customer" ) ,
ephemeralKeySecret = responseJson . getString ( "ephemeralKey" )
)
val publishableKey = responseJson . getString ( "publishableKey" )
PaymentConfiguration . init ( context , publishableKey )
}
}
}
}
private fun onPaymentSheetResult ( paymentSheetResult : PaymentSheetResult ) {
}
When the customer taps your checkout button, call presentWithPaymentIntent to present the payment sheet. After the customer completes the payment, the sheet dismisses and the PaymentSheetResultCallback is called with a 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
@OptIn ( ExperimentalCustomerSessionApi :: class )
@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 (
id = responseJson . getString ( "customer" ) ,
ephemeralKeySecret = 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 は payment_intent.succeeded イベントを送信します。ダッシュボードの Webhook ツール を使用するか Webhook のガイド に従ってこれらのイベントを受信し、顧客への注文確認メールの送信、データベースでの売上の記録、配送ワークフローの開始などのアクションを実行します。
クライアントからのコールバックを待つのではなく、これらのイベントをリッスンします。クライアントでは、コールバックが実行される前に顧客がブラウザーのウィンドウを閉じたり、アプリを終了する場合、また悪意を持つクライアントがレスポンスを不正操作する場合もあります。非同期型のイベントをリッスンするよう組み込みを設定すると、単一の組み込みで複数の異なるタイプの支払い方法 を受け付けることができます。
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 桁の可変長です。 クレジットカード番号と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。
実装内容をテストするためのその他の情報については、テスト をご覧ください。
手数料を回収する When a payment is processed, rather than transfer the full amount of the transaction to a connected account, your platform can decide to take a portion of the transaction amount in the form of fees. You can set fee pricing in two different ways:
Use the Platform Pricing Tool to set and test application fee pricing rules. This no-code feature in the Stripe Dashboard is currently only available for platforms responsible for paying Stripe fees.
Set your pricing rules in-house, specifying fees directly in a PaymentIntent using either the application_fee_amount or transfer_data[amount] parameter. Fees set with this method override the pricing logic specified in the Platform Pricing Tool.
application_ fee_ amount
を指定して支払いを作成すると、支払いのキャプチャー後に、支払いの総額が即座にプラットフォームから transfer_ data[destination]
アカウントに送金されます。その後、application_ fee_ amount
(上限は支払い総額) がプラットフォームに送金されます。
curl https://api.stripe.com/v1/payment_intents \
-u "sk_test_BQokikJOvBiI2HlWgH4olfQ2
:" \
-d amount = 1000 \
-d currency = usd \
-d "automatic_payment_methods[enabled]" = true \
-d application_fee_amount = 123 \
-d "transfer_data[destination]" =
プラットフォーム手数料が回収されると、Application Fee (プラットフォーム手数料) オブジェクトが作成されます。プラットフォーム手数料のリストは、ダッシュボード 、プラットフォーム手数料 、または Sigma で確認できます。プラットフォーム手数料オブジェクトの amount
プロパティを使用して、項目別の手数料レポートを作成することもできます。
application_ fee_ amount
を使用する際には、以下の点に留意します。
application_ fee_ amount
は合計取引額が上限です。application_ fee_ amount
は常に取引と同じ通貨で計算されます。プラットフォーム手数料は、連結アカウントの売上処理通貨と同じ通貨で 売上として処理 されます。クロスボーダーデスティネーション支払いの場合は、プラットフォームの売上処理通貨と異なる 通貨になる場合があります。 application_ fee_ amount
がお客様のアカウントに送金された後に、お客様のプラットフォームが Stripe 手数料を支払います。金額には追加の Stripe 手数料は適用されません。 プラットフォームは埋め込みのプラットフォーム手数料レポートを使用して、回収した手数料 を照合できます。 Stripe がオンラインで提供するダッシュボードや、支払い詳細コンポーネント などのコンポーネントでは、連結アカウントは合計金額とプラットフォーム手数料のどちらの金額も表示できます。 売上のフロー 上記のコードでは、支払いの全額 (10.00 USD) が連結アカウントの保留残高に追加されます。application_ fee_ amount
(1.23 USD) はその支払い金額から差し引かれ、お客様のプラットフォームに送金されます。 次に Stripe 手数料 (0.59 USD) がプラットフォームアカウントの残高から差し引かれます。プラットフォーム手数料から Stripe 手数料を差し引いた金額 (1.23 USD - 0.59 USD = 0.64 USD) は、プラットフォームアカウントの残高に残ります。
通常の Stripe 支払いからの売上と同様に、プラットフォームアカウントの通常の送金スケジュールで application_ fee_ amount
が利用可能になります。
売上処理加盟店を指定する 売上処理加盟店は、アカウントに設定されたケイパビリティ と支払いの作成方法によって決まります。売上処理加盟店は、支払いの作成に誰の情報を使用するかを決定します。これには、その支払いに使用される顧客のクレジットカードまたは銀行口座の明細に表示される明細書表記 (プラットフォームまたは連結アカウントのもの) が含まれます。
売上処理加盟店を指定することにより、誰に対して支払いを作成するかをより明確にすることができます。たとえば、一部のプラットフォームは最終顧客がプラットフォーム (オンデマンドプラットフォームなど) と直接やり取りすることを理由として、売上処理加盟店となることを希望します。ただし、これと異なり最終顧客と直接やり取りする連結アカウントが存在するプラットフォームもあります (E コマースプラットフォーム上のストアなど)。こうしたシナリオでは、連結アカウントを売上処理加盟店にするのが合理的です。
連結アカウントの ID に on_ behalf_ of
パラメーターを設定して、そのアカウントを支払いの売上処理加盟店にすることができます。on_ behalf_ of
を使用すると、以下のようになります。
連結アカウントの国と売上処理通貨 を使用して、支払いが売上として処理 されます。 連結アカウントの国の手数料体系が使用されます。 連結アカウントの明細書表記が顧客のクレジットカード明細書に表示されます。 連結アカウントがプラットフォームと異なる国に所在する場合、連結アカウントの住所と電話番号が顧客のクレジットカード明細書に表示されます。 入金前の保留中の残高 が保持される日数は、連結アカウントの delay_days 設定によって異なります。 on_ behalf_ of
が省略された場合、プラットフォームが取引に関する金銭的責任を負います。
注意 on_ behalf_ of
パラメーターは、card_payments などの支払いケイパビリティを持つ連結アカウントのみで利用できます。受取人利用規約 が適用されているアカウントは、card_ payments
やその他の支払いケイパビリティをリクエストできません。
返金する Payment Intents API を使用している場合、返金は最も最近に作成された支払い に対して発行する必要があります。
プラットフォームアカウントで作成された支払いは、プラットフォームアカウントのシークレットキーを使用して返金できます。transfer_ data[destination]
が設定された支払いを返金する場合、デフォルトではデスティネーションアカウントがそこに送金された売上を保持し、プラットフォームアカウントがその返金からマイナスの残高をカバーします。その返金をカバーするために連結アカウントから売上を取り戻すには、返金を作成する際に reverse_ transfer
パラメータを true
に設定します。
curl https://api.stripe.com/v1/refunds \
-u sk_test_BQokikJOvBiI2HlWgH4olfQ2
: \
-d charge = "{CHARGE_ID}" \
-d reverse_transfer = true \
デフォルトでは支払い額すべてが返金されますが、amount
値を正の整数に設定することで、一部返金を作成することができます。
その払い戻しによって支払い額全額が返金される場合、送金額全額が差し戻しされます。それ以外の場合には、送金額の比例配分された部分が差し戻しされます。
プラットフォーム手数料を返金する プラットフォーム手数料が含まれる支払いを返金すると、デフォルトではプラットフォームアカウントがプラットフォーム手数料の売上を確保します。プラットフォーム手数料の売上を連結アカウントに戻すには、返金を作成する際に refund_application_fee パラメーターに true
を設定します。
curl https://api.stripe.com/v1/refunds \
-u sk_test_BQokikJOvBiI2HlWgH4olfQ2
: \
-d charge = "{CHARGE_ID}" \
-d reverse_transfer = true \
-d refund_application_fee = true \
デスティネーション支払いのプラットフォーム手数料を返金する場合には、送金も差し戻す必要があることに注意します。その返金によって支払い額全額が返金される場合、プラットフォーム手数料の全額も払い戻されます。それ以外の場合には、プラットフォーム手数料の比例配分された部分が返金されます。
別の方法として、false 値の refund_ application_ fee
を指定し、API を通じて プラットフォーム手数料を別途返金することもできます。
失敗した返金 返金が失敗した場合、またはキャンセル した場合、失敗した返金額はプラットフォームアカウントの Stripe 残高に戻されます。必要に応じて、送金 を作成して、資金を連結アカウントに移動します。
不審請求の申請を処理する デスティネーション支払いでは、on_ behalf_ of
の有無にかかわらず、プラットフォームアカウントから不審請求の申請に係る金額と手数料が引き落とされます。
We recommend setting up a webhook to listen to dispute created events . When that happens, you can attempt to recover funds from the connected account by reversing the transfer through the Dashboard or by creating a transfer reversal .
If the connected account has a negative balance, Stripe attempts to debit its external account if debit_ negative_ balances
is set to true
.
If you challenge the dispute and win, you can transfer the funds that you previously reversed back to the connected account. If your platform has an insufficient balance, the transfer fails. Prevent insufficient balance errors by adding funds to your Stripe balance .
よくある間違い Retransferring a previous reversal is subject to cross-border transfer restrictions , meaning you might have no means to repay your connected account. Instead, wait to recover disputed cross-border payment transfers for destination charges with on_ behalf_ of
until after a dispute is lost.
参照情報