メインコンテンツへスキップ

ShopeePay Jump App

ShopeePay モバイルアプリへのアプリ間リダイレクトによる決済を受け付け、シームレスなモバイル決済体験を提供します。

概要

ShopeePay Jump App は、お客様のモバイルアプリやウェブサイトから ShopeePay モバイルアプリへ直接ディープリンクで遷移させるアプリ間リダイレクト決済方式です。QRコードのスキャンと比較して、より高速でネイティブなモバイル体験を提供します。

主な特徴:

  • アプリ間リダイレクト - ShopeePay アプリへの直接ディープリンク
  • 複数の支払いオプション - ウォレット、カード、銀行口座、SPayLater
  • 3つの市場 - タイ、シンガポール、マレーシア
  • 高速な決済 - ネイティブアプリ体験
  • プラットフォーム検出 - iOS と Android に対応
  • 180日間の返金期間 - 全額および一部返金に対応
有効化が必要

ShopeePay Jump App を加盟店アカウントで有効にするには、support@omise.co までお問い合わせください。

対応地域

地域通貨最小金額最大金額API バージョン
タイTHB฿20.00฿150,000.002017-11-02
シンガポールSGD$1.00$20,000.002017-11-02
マレーシアMYRRM1.00RM9,999.002017-11-02

地域別の支払いオプション

支払いオプションタイシンガポールマレーシア
ウォレット残高
クレジットカード
口座振替 / 銀行
SPayLater (BNPL)

仕組み

決済フロー:

  1. お客様がモバイルデバイスで ShopeePay を選択
  2. 加盟店が shopeepay_jumpapp タイプでソースを作成
  3. お客様がディープリンク経由でリダイレクト
  4. ShopeePay アプリが自動的に開く
  5. お客様が支払い方法を選択(ウォレット、カード、SPayLater)
  6. お客様が認証して確認
  7. お客様が加盟店のアプリ/サイトに戻る
  8. Webhook で支払いステータスを確認

通常の完了時間: 30秒〜2分

実装

ステップ 1: ソースの作成

curl https://api.omise.co/sources \
-u $OMISE_PUBLIC_KEY: \
-d "amount=50000" \
-d "currency=THB" \
-d "type=shopeepay_jumpapp" \
-d "platform_type=ANDROID"

ステップ 2: 課金の作成

curl https://api.omise.co/charges \
-u $OMISE_SECRET_KEY: \
-d "amount=50000" \
-d "currency=THB" \
-d "return_uri=https://example.com/payment/complete" \
-d "source=src_test_xxx"

一括リクエスト

ソースと課金を1回のリクエストで作成:

curl https://api.omise.co/charges \
-u $OMISE_SECRET_KEY: \
-d "amount=50000" \
-d "currency=THB" \
-d "return_uri=https://example.com/payment/complete" \
-d "source[type]=shopeepay_jumpapp" \
-d "source[platform_type]=ANDROID"

ステップ 3: お客様のリダイレクト

// プラットフォームを検出してリダイレクト
function redirectToShopeePay(authorizeUri) {
// authorize_uri にディープリンクが含まれています
window.location.href = authorizeUri;
}

// 課金作成後
redirectToShopeePay(charge.authorize_uri);

ステップ 4: 戻りの処理

app.get('/payment/complete', async (req, res) => {
try {
// 課金ステータスを取得
const chargeId = req.query.charge;
const charge = await omise.charges.retrieve(chargeId);

if (charge.status === 'successful') {
await fulfillOrder(charge.metadata.order_id);
res.redirect('/order-success');
} else if (charge.status === 'failed') {
res.redirect('/payment-failed?error=' + charge.failure_code);
} else {
// まだ保留中 - Webhook を待つ
res.redirect('/payment-pending');
}
} catch (error) {
res.redirect('/payment-error');
}
});

ステップ 5: Webhook の処理

app.post('/webhooks/omise', (req, res) => {
const event = req.body;

if (event.key === 'charge.complete') {
const charge = event.data;

if (charge.source.type === 'shopeepay_jumpapp') {
if (charge.status === 'successful') {
fulfillOrder(charge.metadata.order_id);
} else if (charge.status === 'failed') {
handleFailedPayment(charge);
}
}
}

res.status(200).send('OK');
});

完全な実装例

const express = require('express');
const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY
});

const app = express();
app.use(express.json());

// 決済エンドポイント
app.post('/checkout/shopeepay-jumpapp', async (req, res) => {
try {
const { amount, currency, order_id, platform_type } = req.body;

// 通貨を検証
if (!['THB', 'SGD', 'MYR'].includes(currency)) {
return res.status(400).json({
error: 'Currency not supported. Use THB, SGD, or MYR.'
});
}

// プラットフォームを検証
const platform = ['IOS', 'ANDROID'].includes(platform_type)
? platform_type
: 'ANDROID';

// ソースを作成
const source = await omise.sources.create({
type: 'shopeepay_jumpapp',
amount: amount,
currency: currency,
platform_type: platform
});

// 20分の有効期限で課金を作成
const charge = await omise.charges.create({
amount: amount,
currency: currency,
source: source.id,
return_uri: `${process.env.BASE_URL}/payment/complete`,
metadata: {
order_id: order_id
}
});

// ディープリンク URL を返す
res.json({
authorize_uri: charge.authorize_uri,
charge_id: charge.id,
expires_at: charge.expires_at
});

} catch (error) {
console.error('ShopeePay Jump App error:', error);
res.status(500).json({ error: error.message });
}
});

// 戻りハンドラ
app.get('/payment/complete', async (req, res) => {
const chargeId = req.query.charge;

try {
const charge = await omise.charges.retrieve(chargeId);

if (charge.status === 'successful') {
res.redirect(`/order-confirmation?order=${charge.metadata.order_id}`);
} else {
res.redirect(`/payment-failed?charge=${chargeId}`);
}
} catch (error) {
res.redirect('/payment-error');
}
});

// Webhook ハンドラ
app.post('/webhooks/omise', (req, res) => {
const event = req.body;

if (event.key === 'charge.complete') {
const charge = event.data;

if (charge.source.type === 'shopeepay_jumpapp') {
if (charge.status === 'successful') {
processOrder(charge.metadata.order_id);
sendConfirmationEmail(charge);
} else {
notifyPaymentFailure(charge);
}
}
}

res.sendStatus(200);
});

app.listen(3000);

モバイルアプリ統合

iOS (Swift)

func openShopeePayJumpApp(authorizeUri: String) {
guard let url = URL(string: authorizeUri) else { return }

UIApplication.shared.open(url, options: [:]) { success in
if !success {
// ShopeePay アプリがインストールされていない - フォールバックを表示
self.showAppStorePrompt()
}
}
}

Android (Kotlin)

fun openShopeePayJumpApp(authorizeUri: String) {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(authorizeUri))

try {
startActivity(intent)
} catch (e: ActivityNotFoundException) {
// ShopeePay アプリがインストールされていない - フォールバックを表示
showPlayStorePrompt()
}
}

React Native

import { Linking } from 'react-native';

const openShopeePayJumpApp = async (authorizeUri) => {
try {
const supported = await Linking.canOpenURL(authorizeUri);

if (supported) {
await Linking.openURL(authorizeUri);
} else {
// アプリストアへのフォールバック
showAppStorePrompt();
}
} catch (error) {
console.error('Failed to open ShopeePay:', error);
}
};

課金の有効期限

デフォルトの課金有効期限は 20分 です。最大 60分 までカスタマイズできます:

curl https://api.omise.co/charges \
-u $OMISE_SECRET_KEY: \
-d "amount=50000" \
-d "currency=THB" \
-d "source=src_test_xxx" \
-d "return_uri=https://example.com/complete" \
-d "expires_at=2024-12-31T23:59:59Z"

課金ステータスの値

ステータス説明
pendingShopeePay アプリでのお客様の承認待ち
successful支払い完了
failed支払いが拒否されたかエラーが発生
expiredお客様が有効期限内に完了しなかった

失敗コード

コード説明
payment_expired承認期間が終了
payment_rejectedShopeePay が取引を拒否
insufficient_balanceウォレット残高不足
failed_processing一般的な処理エラー

返金

ShopeePay Jump App は 180日以内 の全額および一部返金に対応しています:

// 全額または一部返金
const refund = await omise.charges.refund('chrg_test_xxx', {
amount: 25000 // THB 250.00 の一部返金
});
オフアス取引

「オフアス」取引(ShopeePay ウォレットを直接経由せずにカードや銀行口座で行われた支払い)については、返金およびキャンセルはご利用いただけません。

ベストプラクティス

  1. プラットフォームの検出 - 常に正しい platform_type(IOS/ANDROID)を検出して渡す
  2. アプリ未インストール時の処理 - ShopeePay アプリがインストールされていない場合のフォールバックを提供する
  3. モバイル専用 - この方式は ShopeePay アプリがインストールされたモバイルデバイスが必要
  4. 適切な有効期限の設定 - 有効期限を決済セッションに合わせる
  5. Webhook を優先 - 注文処理には常に Webhook を使用する

よくある質問

ShopeePay Jump App と ShopeePay QR の違いは何ですか?

ShopeePay Jump App (shopeepay_jumpapp): ShopeePay モバイルアプリへ直接ディープリンクするアプリ間リダイレクション方式です。モバイルアプリ統合に適しています。

ShopeePay QR (shopeepay): お客様が ShopeePay アプリでスキャンする QR コードを表示します。デスクトップとモバイルの両方で動作します。

お客様はどの支払い方法を使用できますか?

お客様は以下の方法で支払いが可能です:

  • ShopeePay ウォレット残高 - 全地域
  • クレジット/デビットカード - タイ、シンガポール
  • 口座振替 / 銀行口座 - タイのみ
  • SPayLater (BNPL) - タイ、シンガポール

利用可能なオプションはお客様の地域とアカウント設定によって異なります。

SPayLater とは何ですか?

SPayLater は Shopee の後払い(Buy Now Pay Later)サービスで、お客様が分割払いで支払うことができます。タイとシンガポールで利用可能です。お客様は Shopee アプリを通じて SPayLater のクレジットを申請します。

プラットフォームタイプを指定する必要がありますか?

platform_type パラメータ(IOS または ANDROID)はオプションですが、指定することを推奨します。お客様のデバイスに合わせてディープリンクを最適化するのに役立ちます。指定されない場合、システムは自動的に検出を試みます。

お客様が ShopeePay アプリをインストールしていない場合はどうなりますか?

ShopeePay アプリがインストールされていない場合、ディープリンクは機能しません。以下のようなフォールバックを実装してください:

  1. アプリが正常に開いたかを検出する
  2. 開かない場合はアプリストアにリダイレクトする
  3. 代替の支払い方法を提供する
お客様が支払いを完了するまでの時間はどれくらいですか?

デフォルトでは、お客様は支払いを完了するまで 20分 の猶予があります。課金作成時に expires_at パラメータを使用して、最大 60分 まで延長できます。

デスクトップで使用できますか?

ShopeePay Jump App はモバイルデバイス向けに設計されています。デスクトップユーザーには、代わりに ShopeePay QR を使用してください。スマートフォンでスキャンできる QR コードが表示されます。

関連リソース