payment-method-development
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePayment Method Development
支付方式开发
Overview
概述
Creating custom payment methods in Bagisto allows you to integrate any payment gateway or processor with your store. Whether you need local payment methods, cryptocurrency payments, or specialized payment flows, custom payment methods provide the flexibility your business requires.
For our tutorial, we'll create a Custom Stripe Payment method that demonstrates all the essential concepts you need to build any type of payment solution.
在Bagisto中创建自定义支付方式,可让您将任何支付网关或处理器与您的商店集成。无论您需要本地支付方式、加密货币支付还是专业支付流程,自定义支付方式都能为您的业务提供所需的灵活性。
在本教程中,我们将创建一个自定义Stripe支付方式,演示构建任何类型支付解决方案所需的所有核心概念。
When to Apply
适用场景
Activate this skill when:
- Creating new payment methods
- Integrating payment gateways (Stripe, PayPal, Razorpay, etc.)
- Adding payment options to checkout
- Modifying existing payment configurations
- Creating admin configuration for payment methods
在以下场景中启用本技能:
- 创建新的支付方式
- 集成支付网关(Stripe、PayPal、Razorpay等)
- 在结账流程中添加支付选项
- 修改现有支付配置
- 为支付方式创建后台管理配置
Bagisto Payment Architecture
Bagisto支付架构
Bagisto's payment system is built around a flexible method-based architecture that separates configuration from business logic.
Bagisto的支付系统基于灵活的方式化架构构建,将配置与业务逻辑分离。
Core Components
核心组件
| Component | Purpose | Location |
|---|---|---|
| Payment Methods Configuration | Defines payment method properties | |
| Payment Classes | Contains payment processing logic | |
| System Configuration | Admin interface forms | |
| Service Provider | Registers payment method | |
| 组件 | 用途 | 位置 |
|---|---|---|
| 支付方式配置 | 定义支付方式属性 | |
| 支付类 | 包含支付处理逻辑 | |
| 系统配置 | 后台管理界面表单 | |
| 服务提供者 | 注册支付方式 | |
Key Features
核心特性
- Flexible Payment Processing: Support for redirects, APIs, webhooks, or custom flows.
- Configuration Management: Admin-friendly settings interface.
- Multi-channel Support: Different settings per sales channel.
- Security Ready: Built-in CSRF protection and secure handling.
- Extensible Architecture: Easy integration with third-party gateways.
- 灵活的支付处理:支持重定向、API、Webhook或自定义流程。
- 配置管理:对管理员友好的设置界面。
- 多渠道支持:每个销售渠道可设置不同配置。
- 安全就绪:内置CSRF保护和安全处理机制。
- 可扩展架构:轻松集成第三方网关。
Step-by-Step Guide
分步指南
Step 1: Create Package Directory Structure
步骤1:创建包目录结构
bash
mkdir -p packages/Webkul/CustomStripePayment/src/{Payment,Config,Providers}bash
mkdir -p packages/Webkul/CustomStripePayment/src/{Payment,Config,Providers}Step 2: Create Payment Method Configuration
步骤2:创建支付方式配置
File:
packages/Webkul/CustomStripePayment/src/Config/payment-methods.phpphp
<?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,
],
];文件路径:
packages/Webkul/CustomStripePayment/src/Config/payment-methods.phpphp
<?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,
],
];Configuration Properties Explained
配置属性说明
| Property | Type | Purpose | Description |
|---|---|---|---|
| String | Unique identifier | Must match the array key and be used consistently across your payment method. |
| String | Default display name | Shown to customers during checkout (can be overridden in admin). |
| String | Payment method description | Brief explanation of the payment method. |
| String | Payment class namespace | Full path to your payment processing class. |
| Boolean | Default status | Whether the payment method is enabled by default. |
| Integer | Display order | Lower numbers appear first in checkout (0 = first). |
Note: The array key () must match thecustom_stripe_paymentproperty and be used consistently in your payment classcodeproperty, system configuration key path, and route names and identifiers.$code
| 属性 | 类型 | 用途 | 描述 |
|---|---|---|---|
| 字符串 | 唯一标识符 | 必须与数组键保持一致,并在支付方式中统一使用。 |
| 字符串 | 默认显示名称 | 在结账时向客户展示(可在后台管理中覆盖)。 |
| 字符串 | 支付方式描述 | 支付方式的简短说明。 |
| 字符串 | 支付类命名空间 | 支付处理类的完整路径。 |
| 布尔值 | 默认状态 | 支付方式是否默认启用。 |
| 整数 | 显示顺序 | 数值越小在结账时越靠前显示(0为第一位)。 |
注意: 数组键()必须与custom_stripe_payment属性匹配,并在支付类的code属性、系统配置键路径、路由名称和标识符中统一使用。$code
Step 3: Create Payment Class
步骤3:创建支付类
File:
packages/Webkul/CustomStripePayment/src/Payment/CustomStripePayment.phpphp
<?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);
}
}文件路径:
packages/Webkul/CustomStripePayment/src/Payment/CustomStripePayment.phpphp
<?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);
}
}Step 4: Create System Configuration
步骤4:创建系统配置
File:
packages/Webkul/CustomStripePayment/src/Config/system.phpphp
<?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',
],
],
],
];文件路径:
packages/Webkul/CustomStripePayment/src/Config/system.phpphp
<?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',
],
],
],
];System Configuration Field Properties
系统配置字段属性
| Property | Purpose | Description |
|---|---|---|
| Field identifier | Used to store and retrieve configuration values. |
| Field label | Label displayed in the admin form. |
| Input type | |
| Default setting | Initial value when first configured. |
| Multi-store support | Different values per sales channel. |
| Multi-language support | Translatable content per language. |
| Field validation | Rules like |
| 属性 | 用途 | 描述 |
|---|---|---|
| 字段标识符 | 用于存储和检索配置值。 |
| 字段标签 | 在后台表单中显示的标签。 |
| 输入类型 | |
| 默认设置 | 首次配置时的初始值。 |
| 多商店支持 | 每个销售渠道可设置不同值。 |
| 多语言支持 | 可按语言翻译内容。 |
| 字段验证 | 验证规则如 |
Step 5: Create Service Provider
步骤5:创建服务提供者
File:
packages/Webkul/CustomStripePayment/src/Providers/CustomStripePaymentServiceProvider.phpphp
<?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
{
//
}
}文件路径:
packages/Webkul/CustomStripePayment/src/Providers/CustomStripePaymentServiceProvider.phpphp
<?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
{
//
}
}Step 6: Register Your Package
步骤6:注册您的包
- Add to composer.json (in Bagisto root directory):
json
{
"autoload": {
"psr-4": {
"Webkul\\CustomStripePayment\\": "packages/Webkul/CustomStripePayment/src"
}
}
}- Update autoloader:
bash
composer dump-autoload- Register service provider in :
bootstrap/providers.php
php
<?php
return [
App\Providers\AppServiceProvider::class,
// ... other providers ...
Webkul\CustomStripePayment\Providers\CustomStripePaymentServiceProvider::class,
];- Clear caches:
bash
php artisan optimize:clear- 添加到composer.json(在Bagisto根目录中):
json
{
"autoload": {
"psr-4": {
"Webkul\\CustomStripePayment\\": "packages/Webkul/CustomStripePayment/src"
}
}
}- 更新自动加载器:
bash
composer dump-autoload- 在中注册服务提供者:
bootstrap/providers.php
php
<?php
return [
App\Providers\AppServiceProvider::class,
// ... other providers ...
Webkul\CustomStripePayment\Providers\CustomStripePaymentServiceProvider::class,
];- 清除缓存:
bash
php artisan optimize:clearBase Payment Class Reference
基础支付类参考
Location:
packages/Webkul/Payment/src/Payment/Payment.phpAll payment methods extend abstract class:
Webkul\Payment\Payment\Paymentphp
<?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'),
];
}
}位置:
packages/Webkul/Payment/src/Payment/Payment.php所有支付方式都继承自抽象类:
Webkul\Payment\Payment\Paymentphp
<?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'),
];
}
}Key Methods to Implement
需实现的核心方法
| Method | Purpose | Required |
|---|---|---|
| Return URL for redirect payment methods | Yes (abstract) |
| Return payment method logo URL | No (uses default) |
| Return additional info (instructions, etc.) | No (uses default) |
| Override to add custom availability logic | No (uses default) |
| Override if codes are not in convention | No (uses default) |
Implementation Note: Usually, you don't need to explicitly set theproperty because if your codes are properly set, then config data can get properly. However, if codes are not in convention then you might need this property to override the default behavior.$code
| 方法 | 用途 | 是否必填 |
|---|---|---|
| 返回重定向支付方式的URL | 是(抽象方法) |
| 返回支付方式Logo URL | 否(使用默认实现) |
| 返回额外信息(说明等) | 否(使用默认实现) |
| 重写以添加自定义可用性逻辑 | 否(使用默认实现) |
| 若代码不符合约定则重写 | 否(使用默认实现) |
实现说明: 通常您无需显式设置属性,因为如果代码设置正确,配置数据就能正常获取。但如果代码不符合约定,则可能需要通过该属性覆盖默认行为。$code
Built-in Payment Methods
内置支付方式
- 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
- 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
Best Practices for Payment Classes
支付类最佳实践
Error Handling
错误处理
Always implement comprehensive error handling in your payment methods:
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.',
];
}始终在支付方式中实现全面的错误处理:
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.',
];
}Security Considerations
安全注意事项
Always validate and sanitize data before processing payments to protect your application and customers:
php
/**
* 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;
}在处理支付前始终验证和清理数据,以保护您的应用和客户:
php
/**
* 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;
}Logging and Debugging
日志与调试
Proper logging helps you track payment activities and troubleshoot issues without exposing sensitive information:
php
/**
* 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);
}Implementation Note: The methods shown in this section are demonstration examples for best practices. In real-world applications, you need to implement these methods according to your specific payment gateway requirements and business logic. Use these examples as reference guides and adapt them to your particular use case.
合理的日志记录可帮助您跟踪支付活动并排查问题,同时不暴露敏感信息:
php
/**
* 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);
}实现说明: 本节展示的方法是用于演示最佳实践的示例。在实际应用中,您需要根据特定支付网关的要求和业务逻辑实现这些方法。请将这些示例作为参考指南,并根据您的具体用例进行调整。
Example: PayPal Smart Button (Complex Integration)
示例:PayPal智能按钮(复杂集成)
For complex payment integrations like PayPal, see :
packages/Webkul/Paypal/src/Payment/SmartButton.php- Extends PayPal base class which extends Payment.
- Uses PayPal SDK for API calls.
- Implements createOrder, captureOrder, getOrder, refundOrder.
- Handles sandbox/live environment switching.
对于PayPal这类复杂支付集成,请参考:
packages/Webkul/Paypal/src/Payment/SmartButton.php- 继承自PayPal基础类,该类又继承自Payment类。
- 使用PayPal SDK进行API调用。
- 实现了createOrder、captureOrder、getOrder、refundOrder方法。
- 处理沙箱/生产环境切换。
Package Structure
包结构
packages
└── Webkul
└── CustomStripePayment
└── src
├── Payment
│ └── CustomStripePayment.php # Payment processing logic
├── Config
│ ├── payment-methods.php # Payment method definition
│ └── system.php # Admin configuration
└── Providers
└── CustomStripePaymentServiceProvider.php # Registrationpackages
└── Webkul
└── CustomStripePayment
└── src
├── Payment
│ └── CustomStripePayment.php # 支付处理逻辑
├── Config
│ ├── payment-methods.php # 支付方式定义
│ └── system.php # 后台管理配置
└── Providers
└── CustomStripePaymentServiceProvider.php # 注册类Testing
测试
Payment methods can be tested using the checkout tests in .
packages/Webkul/Shop/tests/Feature/Checkout/CheckoutTest.php可使用中的结账测试来测试支付方式。
packages/Webkul/Shop/tests/Feature/Checkout/CheckoutTest.phpKey Files Reference
核心文件参考
| File | Purpose |
|---|---|
| Base abstract class |
| Payment facade methods |
| Default payment methods config |
| Complex payment example |
| Service provider example |
| Simple payment example |
| Payment with additional details |
| 文件 | 用途 |
|---|---|
| 基础抽象类 |
| Payment门面方法 |
| 默认支付方式配置 |
| 复杂支付示例 |
| 服务提供者示例 |
| 简单支付示例 |
| 包含额外信息的支付示例 |
Common Pitfalls
常见陷阱
- Forgetting to merge config in service provider
- Not matching property with config array key
$code - Not registering service provider in
bootstrap/providers.php - Forgetting to run after adding package
composer dump-autoload - Not clearing cache after configuration changes
- Not following PHPDoc conventions with proper punctuation
- 忘记在服务提供者中合并配置
- 属性与配置数组键不匹配
$code - 未在中注册服务提供者
bootstrap/providers.php - 添加包后忘记运行
composer dump-autoload - 修改配置后忘记清除缓存
- 未遵循带正确标点的PHPDoc规范