payment-method-development について
Bagisto の開発者向けに、カスタム決済方法の実装を案内するスキルです。決済クラスや設定、パッケージ登録を扱い、ゲートウェイ連携やチェックアウトの選択肢追加に役立ちます。
主な機能
- 01決済方法と管理設定の構成
- 02決済処理クラスの実装
- 03プロバイダーとパッケージの登録
- 04販売チャネルごとの設定
- 05組み込み決済方法の例
活用シーン
- 01チェックアウトに独自の決済方法を追加
- 02ゲートウェイや専用フローを連携
- 03決済方法の管理設定を作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ bagisto/ agent-skills --skill payment-method-developmentインストール後、Claude Code で/payment-method-developmentを入力して読み込まれたか確認します。
詳細
決済方法の開発
概要
Bagistoでカスタム決済方法を作成すると、任意の決済ゲートウェイや決済プロセッサをストアに統合できます。ローカル決済方法、暗号通貨による決済、または特殊な決済フローが必要な場合でも、カスタム決済方法を使用すれば、ビジネスに必要な柔軟性を確保できます。
このチュートリアルでは、あらゆる種類の決済ソリューションを構築する際に必要となる基本的な概念を紹介するため、Custom Stripe Payment メソッドを作成します。
適用する場面
次の場合に、このスキルを有効にしてください。
- 新しい決済方法を作成するとき
- 決済ゲートウェイ(Stripe、PayPal、Razorpayなど)を統合するとき
- チェックアウトに決済オプションを追加するとき
- 既存の決済設定を変更するとき
- 決済方法の管理画面設定を作成するとき
Bagistoの決済アーキテクチャ
Bagistoの決済システムは、設定とビジネスロジックを分離する、柔軟なメソッドベースのアーキテクチャを採用しています。
主なコンポーネント
| コンポーネント | 目的 | 場所 |
|---|---|---|
| 決済方法の設定 | 決済方法のプロパティを定義します | Config/payment-methods.php |
| 決済クラス | 決済処理ロジックを含みます | Payment/ClassName.php |
| システム設定 | 管理画面のフォームを定義します | Config/system.php |
| サービスプロバイダー | 決済方法を登録します | Providers/ServiceProvider.php |
主な機能
- 柔軟な決済処理:リダイレクト、API、Webhook、またはカスタムフローに対応します。
- 設定管理:管理しやすい設定インターフェースを提供します。
- マルチチャネル対応:販売チャネルごとに異なる設定が可能です。
- セキュリティ対応:CSRF保護と安全な処理機能を標準で備えています。
- 拡張可能なアーキテクチャ:サードパーティのゲートウェイと簡単に統合できます。
手順
ステップ1:パッケージのディレクトリー構造を作成する
mkdir -p packages/Webkul/CustomStripePayment/src/{Payment,Config,Providers}
ステップ2:決済方法の設定を作成する
ファイル: packages/Webkul/CustomStripePayment/src/Config/payment-methods.php
<?php
return [
'custom_stripe_payment' => [
'code' => 'custom_stripe_payment',
'title' => 'Credit Card (Stripe)',
'description' => 'Secure credit card payments powered by Stripe',
'class' => 'Webkul\CustomStripePayment\Payment\CustomStripePayment',
'active' => true,
'sort' => 1,
],
];
設定プロパティの説明
| プロパティ | 型 | 目的 | 説明 |
|---|---|---|---|
code | 文字列 | 一意の識別子 | 配列キーと一致させ、決済方法全体で一貫して使用する必要があります。 |
title | 文字列 | デフォルトの表示名 | チェックアウト時に顧客に表示されます(管理画面で上書きできます)。 |
description | 文字列 | 決済方法の説明 | 決済方法の簡単な説明です。 |
class | 文字列 | 決済クラスの名前空間 | 決済処理クラスへの完全なパスです。 |
active | ブール値 | デフォルトの状態 | 決済方法をデフォルトで有効にするかどうかを指定します。 |
sort | 整数 | 表示順序 | 数値が小さいほどチェックアウト時に先に表示されます(0 = 先頭)。 |
注: 配列キー(
custom_stripe_payment)はcodeプロパティと一致させ、決済クラスの$codeプロパティ、システム設定のキーのパス、ルート名および識別子でも一貫して使用する必要があります。
ステップ3:決済クラスを作成する
ファイル: packages/Webkul/CustomStripePayment/src/Payment/CustomStripePayment.php
<?php
namespace Webkul\CustomStripePayment\Payment;
use Webkul\Payment\Payment\Payment;
class CustomStripePayment extends Payment
{
/**
* Payment method code - must match payment-methods.php key.
*
* @var string
*/
protected $code = 'custom_stripe_payment';
/**
* Get redirect URL for payment processing.
*
* Note: You need to create this route in your Routes/web.php file
* or return null if you don't need a redirect.
*
* @return string|null
*/
public function getRedirectUrl()
{
// return route('custom_stripe_payment.process');
return null; // No redirect needed for this basic example
}
/**
* Get additional details for frontend display.
*
* @return array
*/
public function getAdditionalDetails()
{
return [
'title' => $this->getConfigData('title'),
'description' => $this->getConfigData('description'),
'requires_card_details' => true,
];
}
/**
* Get payment method configuration data.
*
* @param string $field
* @return mixed
*/
public function getConfigData($field)
{
return core()->getConfigData('sales.payment_methods.custom_stripe_payment.' . $field);
}
}
ステップ4:システム設定を作成する
ファイル: packages/Webkul/CustomStripePayment/src/Config/system.php
<?php
return [
[
'key' => 'sales.payment_methods.custom_stripe_payment',
'name' => 'Custom Stripe Payment',
'info' => 'Custom Stripe Payment Method Configuration',
'sort' => 1,
'fields' => [
[
'name' => 'active',
'title' => 'Status',
'type' => 'boolean',
'default_value' => true,
'channel_based' => true,
],
[
'name' => 'title',
'title' => 'Title',
'type' => 'text',
'default_value' => 'Credit Card (Stripe)',
'channel_based' => true,
'locale_based' => true,
],
[
'name' => 'description',
'title' => 'Description',
'type' => 'textarea',
'default_value' => 'Secure credit card payments',
'channel_based' => true,
'locale_based' => true,
],
[
'name' => 'sort',
'title' => 'Sort Order',
'type' => 'text',
'default_value' => '1',
],
],
],
];
システム設定フィールドのプロパティ
| プロパティ | 目的 | 説明 |
|---|---|---|
name | フィールド識別子 | 設定値の保存と取得に使用します。 |
title | フィールドラベル | 管理画面フォームに表示されるラベルです。 |
type | 入力タイプ | text、textarea、boolean、select、passwordなどです。 |
default_value | デフォルト設定 | 初回設定時の初期値です。 |
channel_based | マルチストア対応 | 販売チャネルごとに異なる値を設定できます。 |
locale_based | 多言語対応 | 言語ごとに翻訳可能なコンテンツを設定できます。 |
validation | フィールドの検証 | required、numeric、emailなどのルールです。 |
ステップ 5:サービスプロバイダーを作成する
ファイル: packages/Webkul/CustomStripePayment/src/Providers/CustomStripePaymentServiceProvider.php
<?php
namespace Webkul\CustomStripePayment\Providers;
use Illuminate\Support\ServiceProvider;
class CustomStripePaymentServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register(): void
{
// Merge payment method configuration.
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/payment-methods.php',
'payment_methods'
);
// Merge system configuration.
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/system.php',
'core'
);
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot(): void
{
//
}
}
ステップ 6:パッケージを登録する
- composer.json に追加する(Bagisto のルートディレクトリ内):
{
"autoload": {
"psr-4": {
"Webkul\\CustomStripePayment\\": "packages/Webkul/CustomStripePayment/src"
}
}
}
- オートローダーを更新する:
composer dump-autoload
bootstrap/providers.phpでサービスプロバイダーを登録する:
<?php
return [
App\Providers\AppServiceProvider::class,
// ... other providers ...
Webkul\CustomStripePayment\Providers\CustomStripePaymentServiceProvider::class,
];
- キャッシュをクリアする:
php artisan optimize:clear
基本決済クラスのリファレンス
場所: packages/Webkul/Payment/src/Payment/Payment.php
すべての決済方法は、Webkul\Payment\Payment\Payment 抽象クラスを継承します。
<?php
namespace Webkul\Payment\Payment;
use Webkul\Checkout\Facades\Cart;
abstract class Payment
{
/**
* Cart.
*
* @var \Webkul\Checkout\Contracts\Cart
*/
protected $cart;
/**
* Checks if payment method is available.
*
* @return bool
*/
public function isAvailable()
{
return $this->getConfigData('active');
}
/**
* Get payment method code.
*
* @return string
*/
public function getCode()
{
if (empty($this->code)) {
// throw exception
}
return $this->code;
}
/**
* Get payment method title.
*
* @return string
*/
public function getTitle()
{
return $this->getConfigData('title');
}
/**
* Get payment method description.
*
* @return string
*/
public function getDescription()
{
return $this->getConfigData('description');
}
/**
* Get payment method image.
*
* @return string
*/
public function getImage()
{
return $this->getConfigData('image');
}
/**
* Retrieve information from payment configuration.
*
* @param string $field
* @return mixed
*/
public function getConfigData($field)
{
return core()->getConfigData('sales.payment_methods.'.$this->getCode().'.'.$field);
}
/**
* Abstract method to get the redirect URL.
*
* @return string The redirect URL.
*/
abstract public function getRedirectUrl();
/**
* Set cart.
*
* @return void
*/
public function setCart()
{
if (! $this->cart) {
$this->cart = Cart::getCart();
}
}
/**
* Get cart.
*
* @return \Webkul\Checkout\Contracts\Cart
*/
public function getCart()
{
if (! $this->cart) {
$this->setCart();
}
return $this->cart;
}
/**
* Return cart items.
*
* @return \Illuminate\Database\Eloquent\Collection
*/
public function getCartItems()
{
if (! $this->cart) {
$this->setCart();
}
return $this->cart->items;
}
/**
* Get payment method sort order.
*
* @return string
*/
public function getSortOrder()
{
return $this->getConfigData('sort');
}
/**
* Get payment method additional information.
*
* @return array
*/
public function getAdditionalDetails()
{
if (empty($this->getConfigData('instructions'))) {
return [];
}
return [
'title' => trans('admin::app.configuration.index.sales.payment-methods.instructions'),
'value' => $this->getConfigData('instructions'),
];
}
}
実装する主なメソッド
| メソッド | 目的 | 必須 |
|---|---|---|
getRedirectUrl() | リダイレクト型決済方法のリダイレクト先 URL を返します | はい(抽象メソッド) |
getImage() | 決済方法のロゴ URL を返します | いいえ(デフォルトを使用) |
getAdditionalDetails() | 追加情報(手順など)を返します | いいえ(デフォルトを使用) |
isAvailable() | 独自の利用可否ロジックを追加するためにオーバーライドします | いいえ(デフォルトを使用) |
getConfigData($field) | コードが規約に従っていない場合にオーバーライドします | いいえ(デフォルトを使用) |
実装上の注意: 通常、
$codeプロパティを明示的に設定する必要はありません。コードが適切に設定されていれば、設定データを正しく取得できるためです。ただし、コードが規約に従っていない場合は、デフォルトの動作をオーバーライドするためにこのプロパティが必要になることがあります。
組み込みの決済方法
- CashOnDelivery:
packages/Webkul/Payment/src/Payment/CashOnDelivery.php - MoneyTransfer:
packages/Webkul/Payment/src/Payment/MoneyTransfer.php - PaypalStandard:
packages/Webkul/Paypal/src/Payment/Standard.php - PaypalSmartButton:
packages/Webkul/Paypal/src/Payment/SmartButton.php
決済クラスのベストプラクティス
エラー処理
決済方法には、常に包括的なエラー処理を実装してください。
/**
* Handle payment errors gracefully.
*
* @param \Exception $e
* @return array
*/
protected function handlePaymentError(\Exception $e)
{
// Log the error for debugging.
\Log::error('Payment error in ' . $this->code, [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
// Return user-friendly error message.
return [
'success' => false,
'error' => 'Payment processing failed. Please try again or contact support.',
];
}
セキュリティに関する考慮事項
アプリケーションと顧客を保護するため、決済を処理する前に必ずデータを検証し、サニタイズしてください。
/**
* Validate payment data before processing.
*
* @param array $data
* @return bool
*
* @throws \InvalidArgumentException
*/
protected function validatePaymentData($data)
{
$validator = validator($data, [
'amount' => 'required|numeric|min:0.01',
'currency' => 'required|string|size:3',
'customer_email'=> 'required|email',
]);
if ($validator->fails()) {
throw new \InvalidArgumentException($validator->errors()->first());
}
return true;
}
ロギングとデバッグ
適切なロギングにより、機密情報を漏らすことなく決済の操作を追跡し、問題をトラブルシューティングできます。
/**
* Log payment activities for debugging and audit.
*
* @param string $action
* @param array $data
* @return void
*/
protected function logPaymentActivity($action, $data = [])
{
// Remove sensitive data before logging.
$sanitizedData = array_diff_key($data, [
'api_key' => '',
'secret_key' => '',
'card_number' => '',
'cvv' => '',
]);
\Log::info("Payment {$action} for {$this->code}", $sanitizedData);
}
実装上の注意: このセクションで示すメソッドは、ベストプラクティスのデモ用の例です。実際のアプリケーションでは、各決済ゲートウェイの要件とビジネスロジックに従って、これらのメソッドを実装する必要があります。これらの例を参考にし、具体的なユースケースに合わせて調整してください。
例:PayPal Smart Button(複雑な連携)
PayPal のような複雑な決済連携については、packages/Webkul/Paypal/src/Payment/SmartButton.php を参照してください。
- Payment を継承した PayPal の基本クラスを継承します。
- API 呼び出しには PayPal SDK を使用します。
- createOrder、captureOrder、getOrder、refundOrder を実装します。
- サンドボックス環境と本番環境の切り替えに対応します。
パッケージ構成
packages
└── Webkul
└── CustomStripePayment
└── src
├── Payment
│ └── CustomStripePayment.php # Payment processing logic
├── Config
│ ├── payment-methods.php # Payment method definition
│ └── system.php # Admin configuration
└── Providers
└── CustomStripePaymentServiceProvider.php # Registration
テスト
決済方法は、packages/Webkul/Shop/tests/Feature/Checkout/CheckoutTest.php のチェックアウトテストを使用してテストできます。
主なファイルのリファレンス
| ファイル | 目的 |
|---|---|
packages/Webkul/Payment/src/Payment/Payment.php | 基本抽象クラス |
packages/Webkul/Payment/src/Payment.php | 決済ファサードのメソッド |
packages/Webkul/Payment/src/Config/payment-methods.php | デフォルトの決済方法設定 |
packages/Webkul/Paypal/src/Payment/SmartButton.php | 複雑な決済の例 |
packages/Webkul/Paypal/src/Providers/PaypalServiceProvider.php | サービスプロバイダーの例 |
packages/Webkul/Payment/src/Payment/CashOnDelivery.php | シンプルな決済の例 |
packages/Webkul/Payment/src/Payment/MoneyTransfer.php | 追加情報を含む決済 |
よくある落とし穴
- サービスプロバイダーで設定をマージし忘れる
$codeプロパティと設定配列のキーが一致していないbootstrap/providers.phpにサービスプロバイダーを登録していない- パッケージを追加した後に
composer dump-autoloadを実行し忘れる - 設定を変更した後にキャッシュをクリアしていない
- 適切な句読点を使った PHPDoc の規約に従っていない