SocoPay 支付服务 Composer 包,封装下单、取消订单、查看支付状态和支付状态回调验签。
composer require socopay/payment本包不会直接读取业务项目的 .env。调用方应在自己的项目里维护配置文件,例如 Laravel/ThinkPHP 项目可放在 config/socopay.php,再把配置数组传给 Payment。
config/socopay.php 示例:
return [
'app_id' => env('SOCOPAY.SOCOPAY_APP_ID', ''),
'app_key' => env('SOCOPAY.SOCOPAY_APP_KEY', ''),
'currency_code' => env('SOCOPAY.SOCOPAY_CURRENCY_CODE', 'CNY'),
'environment' => env('SOCOPAY.SOCOPAY_ENVIRONMENT', 'sandbox'),
'algorithm' => env('SOCOPAY.SOCOPAY_SIGN_ALGORITHM', 'md5'),
'timeout' => env('SOCOPAY.SOCOPAY_TIMEOUT', 10),
'notify_url' => env('SOCOPAY.SOCOPAY_NOTIFY_URL', ''),
];.env 示例:
[SOCOPAY]
SOCOPAY_APP_ID=apcXXXXXXXXXXXXXXXXXXXXX
SOCOPAY_APP_KEY=your-app-key
SOCOPAY_CURRENCY_CODE=CNY
# sandbox, production
SOCOPAY_ENVIRONMENT=sandbox
# md5, sha256, sha512
SOCOPAY_SIGN_ALGORITHM=md5
SOCOPAY_TIMEOUT=10
SOCOPAY_NOTIFY_URL=https://api.test.com/notify
调用时传入项目自己的配置:
use Socopay\Payment\Payment;
$payment = new Payment(config('socopay'));默认环境地址:
- Sandbox:
https://api.socolar.com/ - Production:
https://pay.socolar.com/
$response = $payment->newOrder([
'source_order_no' => 'APCpublishorder0525001',
'real_payment' => '1000.01',
'due_payment' => '',
'discount' => '',
'product_subject' => 'article processing charge test',
'product_detail' => [ // 除了非必填项,其他的都是必填 & 值不为空
'org_name' => 'Tsinghua university',
'org_code' => 'https://ror.org/03cve4549', // 非必填
'article_id' => 'mdpi123456',
'article_title' => 'Modified Senning Operation in the Treatment of Transposition of The Great Arteries',
'authors' => 'author1;author2;author3;',
'journal_title' => 'journal title',
'doi' => 'doi123456',
'redirect_url' => 'https://www.publisher.com/return', // 非必填
'accepted_date' => '6/20/2023' // 非必填
'submission_date' => '5/20/2023' // 非必填
'keywords' => 'keywords1;keywords2;keywords3;' // 非必填
],
'user_id' => 'zengdanid',
'user_name' => 'zengdan',
'user_email' => 'zengdanq@163.com',
'user_phone' => '13611111111',
'orcid' => '123456', // 值可为空
'pay_deadline' => '2026-12-30',
//'notify_url' => 'https://www.publisher.com/notificationapi',
'extend_params' => '',
'passback_params' => '',
]);
// (notify_url, extend_params, passback_params, pay_deadline, orcid, user_phone, discount, due_payment)值可为空, 键必填
$payUrl = $response['Data']['pay_url'] ?? null;$response = $payment->cancelOrder('APCpublishorder0525001');$payload = json_decode(file_get_contents('php://input'), true) ?: [];
if (!$payment->verifyNotification($payload)) {
http_response_code(400);
exit('invalid sign');
}
/**
* 0 表示未支付/待处理;1 表示部分支付;2 表示全额支付;-1 表示未找到订单或订单已被取消;
* 1001 表示用户选择了线下支付方式但 SocoPay 尚未收到资金。
*/
$state = (int) $payload['state'];/**
* 0 表示未支付/待处理;1 表示部分支付;2 表示全额支付;-1 表示未找到订单或订单已被取消;
* 1001 表示用户选择了线下支付方式但 SocoPay 尚未收到资金。
*/
$response = $payment->checkPayState('APCpublishorder0525001, APdpublishorder0623002');包内签名实现遵循 SocoPay 文档:
- 排除
sign字段。 - 将请求字段统一转换为字符串;数组先递归转换内部字段值,再转换为 JSON 字符串,
null转为空字符串。 - 按字段名 ASCII 升序排序。
- 将值按 RFC3986 进行 URL 编码。
- 追加
key=app_key。 - 将整个待签名字符串转为小写。
- 使用预设算法
md5、sha256或sha512生成签名。
接口请求失败、SocoPay 返回失败状态或响应不是合法 JSON 时,会抛出 Socopay\Payment\SocopayException。可通过 responseBody() 获取 SocoPay 原始响应数组。
下单前会先检查必需键是否存在。product_detail 必须是嗯非空数组,并且包含 article_title、article_id、authors、journal_title、org_name、doi。