zeldein / mylaravel-newebpay
连接newebpay API服务的库。
Requires
- php: >=8.1
- guzzlehttp/guzzle: >=7.2
- illuminate/config: >=9.0
- illuminate/contracts: >=9.0
- illuminate/log: >=9.0
- illuminate/support: >=9.0
- ycs77/laravel-recover-session: ^1.1
Requires (Dev)
- mockery/mockery: ^1.4
- orchestra/testbench: >=7.0
- pestphp/pest: ^2.6
README
Laravel NewebPay 是针对 Laravel 编写的蓝新支付(智付通)支付接口套件。
主要实现项目:
- NewebPay MPG - 多功能收款
- NewebPay Query - 单笔交易查询
- NewebPay Cancel - 信用卡取消授权
- NewebPay Close - 信用卡退款
- NewebPay Period - 信用卡定期定额委托
- NewebPay Period Alter Status - 修改委托状态
- NewebPay Period Alter Amt - 修改委托内容
版本需求
- PHP 支持 8.1 以上
- Laravel 版本 9 以上
安装
composer require ycs77/laravel-newebpay
发布配置文件
php artisan vendor:publish --tag=newebpay-config
注册蓝新支付商店
首先,到蓝新支付的网站上注册账号(测试时需要注册测试账号)并建立商店。然后在“商店资料设置”中启用需要使用的支付功能(测试时可以尽量全部启用),并复制商店接口API的商店代号、HashKey 和 HashIV。
在 .env 中设置商店代号和 HashKey 等:
NEWEBPAY_STORE_ID=... # 貼上 商店代號 (Ex: MS3311...)
NEWEBPAY_STORE_HASH_KEY=... # 貼上 HashKey
NEWEBPAY_STORE_HASH_IV=... # 貼上 HashIV
NEWEBPAY_DEBUG=true # 測試模式
更多设置需打开 config/newebpay.php 修改。
测试账号
测试环境仅接受以下测试信用卡号:
- 4000-2211-1111-1111 (一次性付款+分期付款)
- 4003-5511-1111-1111 (红利折抵)
测试卡号有效月年及卡片背面末三码,可任意填写。
更多详细信息请参考蓝新支付 API 文件。
MPG 多功能付款
发送付款请求页面
首先先建立一个页面,和一個“付款”按钮:
routes/web.php
Route::get('/pay', function () { return view('pay'); });
resources/views/pay.blade.php
<form action="/pay" method="POST"> @csrf <button>付款</button> </form>
Inertia.js 可以参考以下:
routes/web.php
Route::get('/pay', function () { return Inertia::render('Pay', [ 'csrfToken' => csrf_token(), ]); });
resources/js/pages/Pay.vue
<template> <form action="/pay" method="POST"> <input type="hidden" name="_token" :value="csrfToken"> <button>付款</button> </form> </template> <script setup> defineProps({ csrfToken: String, }) </script>
然后建立发送付款的路由:
use Ycs77\NewebPay\Facades\NewebPay; Route::post('/pay', function () { $no = 'Vanespl_ec_'.time(); // 訂單編號 $amt = 120; // 交易金額 $desc = '我的商品'; // 商品名稱 $email = 'test@example.com'; // 付款人信箱 return NewebPay::payment($no, $amt, $desc, $email)->submit(); });
基本上一般交易可直接在 config/newebpay.php 做设置,里面有详细的说明,但如果遇到特殊情况,可以按照个别交易设置:
use Ycs77\NewebPay\Facades\NewebPay; return NewebPay::payment(...) ->lang() // 語言設定 ->tradeLimit() // 交易秒數限制 ->expireDate() // 交易截止日 ->returnUrl() // 由藍新回傳後前景畫面要接收資料顯示的網址 ->notifyUrl() // 由藍新回傳後背景處理資料的接收網址 ->customerUrl() // 商店取號網址 ->clientBackUrl() // 付款時點擊「返回按鈕」的網址 ->emailModify() // 是否開放 email 修改 ->loginType() // 是否需要登入藍新金流會員 ->orderComment() // 商店備註 ->paymentMethod() // 付款方式 *依照 config 格式傳送* ->CVSCOM() // 物流方式 ->lgsType() // 物流型態 ->submit();
付款请求返回结果
发送付款之后当然是要建立返回的路由,如果是信用卡等付款方式,可以付款后直接跳转回本网站的,可以只设置 callback:
use Illuminate\Http\Request; use Ycs77\NewebPay\Facades\NewebPay; Route::post('/pay/callback', function (Request $request) { $result = NewebPay::result($request); if ($result->isFail()) { return redirect()->to('/pay')->with('error', $result->message()); } // 訂單付款成功,處裡訂單邏輯... return redirect()->to('/pay')->with('success', '付款成功'); });
如果是 ATM 的付款方式,需要通过幕后返回的,可以只设置 notify:
use Illuminate\Http\Request; use Ycs77\NewebPay\Facades\NewebPay; Route::post('/pay/notify', function (Request $request) { $result = NewebPay::result($request); if ($result->isFail()) { return; } logger('藍新金流 交易資訊 notify', ['result' => $result->data()]); // 訂單付款成功,處裡訂單邏輯... });
返回结果可以使用各种方法来获取所需的数据:
$result = NewebPay::result($request); $result->data(); // 回傳完整結果 $result->status(); // 交易狀態:若交易付款成功,則回傳 SUCCESS。若交易付款失敗,則回傳錯誤代碼。 $result->isSuccess(); // 交易是否成功 $result->isFail(); // 交易是否失敗 $result->message(); // 敘述此次交易狀態 $result->result(); // 回傳參數 $result->merchantId(); // 藍新金流商店代號 $result->amt(); // 交易金額 $result->tradeNo(); // 藍新金流交易序號 $result->merchantOrderNo(); // 商店訂單編號 $result->respondType(); // 回傳格式 $result->payTime(); // 支付完成時間 $result->ip(); // 交易 IP $result->escrowBank(); // 款項保管銀行 // 信用卡支付回傳(一次付清、Google Pay、Samaung Pay、國民旅遊卡、銀聯) if ($result->paymentType() === 'CREDIT') { $credit = $result->credit(); // 參考:\Ycs77\NewebPay\Results\MPGCreditResult } // WEBATM、ATM 繳費回傳 if ($result->paymentType() === 'VACC' || $result->paymentType() === 'WEBATM') { $atm = $result->atm(); // 參考:\Ycs77\NewebPay\Results\MPGATMResult } // 超商代碼繳費回傳 if ($result->paymentType() === 'CVS') { $storeCode = $result->storeCode(); // 參考:\Ycs77\NewebPay\Results\MPGStoreCodeResult } // 超商條碼繳費回傳 if ($result->paymentType() === 'BARCODE') { $storeBarcode = $result->storeBarcode(); // 參考:\Ycs77\NewebPay\Results\MPGStoreBarcodeResult } // 超商物流回傳 if ($result->paymentType() === 'CVSCOM') { $lgs = $result->lgs(); // 參考:\Ycs77\NewebPay\Results\MPGLgsResult } // 跨境支付回傳 (包含簡單付電子錢包、簡單付微信支付、簡單付支付寶) $ezPay = $result->ezPay(); if ($ezPay->isEzPay()) { // 參考:\Ycs77\NewebPay\Results\MPGEzPayResult } // 玉山 Wallet 回傳 if ($result->paymentType() === 'ESUNWALLET') { $esunWallet = $result->esunWallet(); // 參考:\Ycs77\NewebPay\Results\MPGEsunWalletResult } // 台灣 Pay 回傳 if ($result->paymentType() === 'TAIWANPAY') { $taiwanPay = $result->taiwanPay(); // 參考:\Ycs77\NewebPay\Results\MPGTaiwanPayResult }
但如果同时设置的话,进行部分交易时两个 API 都会发送消息,这时就要各司其职,callback 只设置返回给用户的消息,而 notify 只负责处理交易的逻辑:
use Illuminate\Http\Request; use Ycs77\NewebPay\Facades\NewebPay; Route::post('/pay/callback', function (Request $request) { $result = NewebPay::result($request); if ($result->isFail()) { return redirect()->to('/pay')->with('error', $result->message()); } return redirect()->to('/pay')->with('success', '付款成功'); }); Route::post('/pay/notify', function (Request $request) { $result = NewebPay::result($request); if ($result->isFail()) { return; } logger('藍新金流 交易資訊 notify', ['result' => $result->data()]); // 訂單付款成功,處裡訂單邏輯... });
设置好之后可以在 config/newebpay.php 中设置网址:
return [ // 付款完成後導向頁面 'return_url' => '/pay/callback', // 付款完成後的通知連結 'notify_url' => '/pay/notify', ]
还要把这些路径排除 CSRF 检查:
app/Http/Middleware/VerifyCsrfToken.php
class VerifyCsrfToken extends Middleware { protected $except = [ '/pay/callback', '/pay/notify', ]; }
ATM/超商条码/超商代碼取號
默认会直接导向到蓝新支付的取号页面,没有特别需求不需要自己进行。但如果要自定义取号页面的话,也是可以自己定制调整:
use Ycs77\NewebPay\Facades\NewebPay; Route::post('/pay/customer', function (Request $request) { $result = NewebPay::customer($request); if ($result->isFail()) { // 取號錯誤... return; } $result = $result->result(); // 自訂取號結果頁面... });
在 config/newebpay.php 中设置网址:
return [ // 商店取號網址 'customer_url' => '/pay/customer', ]
然后要把路径排除 CSRF 检查:
app/Http/Middleware/VerifyCsrfToken.php
class VerifyCsrfToken extends Middleware { protected $except = [ ... '/pay/customer', ]; }
单笔交易查询
从订单编号和该笔交易的资金来查询交易详情:
use Ycs77\NewebPay\Facades\NewebPay; function query(Request $request) { $no = $request->input('no'); // 該筆交易的訂單編號 $amt = $request->input('amt'); // 該筆交易的金額 $type = 'order'; // 可選擇是 'order' (訂單編號),或是 'trade' (藍新交易編號) 來做申請 $result = NewebPay::query($no, $amt, $type)->submit(); if ($result->isSuccess() && $result->verify()) { // 查詢成功... return response()->json($result->result()); } return response()->json(['message' => $result->message()]); }
信用卡取消授权
在未请求款之前可以发起取消信用卡交易:
use Ycs77\NewebPay\Facades\NewebPay; function cancel() { $no = $request->input('no'); // 該筆交易的訂單編號 $amt = $request->input('amt'); // 該筆交易的金額 $type = 'order'; // 可選擇是 'order' (訂單編號),或是 'trade' (藍新交易編號) 來做申請 $result = NewebPay::cancel($no, $amt, $type)->submit(); if ($result->isSuccess() && $result->verify()) { return response()->json(['message' => '取消授權成功']); } return response()->json(['message' => $result->message()]); }
信用卡请求/退款
设置信用卡请求、取消请求、退款、取消退款:
use Ycs77\NewebPay\Facades\NewebPay; /** * 信用卡請款 */ function request() { $no = $request->input('no'); // 該筆交易的訂單編號 $amt = $request->input('amt'); // 該筆交易的金額 $type = 'order'; // 可選擇是 'order' (訂單編號),或是 'trade' (藍新交易編號) 來做申請 $result = NewebPay::request($no, $amt, $type)->submit(); if ($result->isSuccess()) { return response()->json(['message' => '信用卡請款成功']); } return response()->json(['message' => $result->message()]); } /** * 信用卡取消請款 */ function cancelRequest() { $no = $request->input('no'); // 該筆交易的訂單編號 $amt = $request->input('amt'); // 該筆交易的金額 $type = 'order'; // 可選擇是 'order' (訂單編號),或是 'trade' (藍新交易編號) 來做申請 $result = NewebPay::cancelRequest($no, $amt, $type)->submit(); if ($result->isSuccess()) { return response()->json(['message' => '信用卡取消請款成功']); } return response()->json(['message' => $result->message()]); } /** * 信用卡退款 */ function refund() { $no = $request->input('no'); // 該筆交易的訂單編號 $amt = $request->input('amt'); // 該筆交易的金額 $type = 'order'; // 可選擇是 'order' (訂單編號),或是 'trade' (藍新交易編號) 來做申請 $result = NewebPay::refund($no, $amt, $type)->submit(); if ($result->isSuccess()) { return response()->json(['message' => '信用卡退款成功']); } return response()->json(['message' => $result->message()]); } /** * 信用卡取消退款 */ function cancelRefund() { $no = $request->input('no'); // 該筆交易的訂單編號 $amt = $request->input('amt'); // 該筆交易的金額 $type = 'order'; // 可選擇是 'order' (訂單編號),或是 'trade' (藍新交易編號) 來做申請 $result = NewebPay::cancelRefund($no, $amt, $type)->submit(); if ($result->isSuccess()) { return response()->json(['message' => '信用卡取消退款成功']); } return response()->json(['message' => $result->message()]); }
或者也可以使用同一个 API 端点来执行请求/退款:
use Ycs77\NewebPay\Facades\NewebPay; /** * 信用卡請/退款 */ function close() { $no = $request->input('no'); // 該筆交易的訂單編號 $amt = $request->input('amt'); // 該筆交易的金額 $type = 'order'; // 可選擇是 'order' (訂單編號),或是 'trade' (藍新交易編號) 來做申請 $result = NewebPay::close($no, $amt, $type) ->closeType($request->query('type')) // 設定請款或退款 ->cancel($request->boolean('cancel')) // 取消請款或退款 ->submit(); if ($result->isSuccess()) { return response()->json(['message' => '請求成功']); } return response()->json(['message' => $result->message()]); }
信用卡定期定额委托
发送建立委托请求页面
首先先建立一个页面,和一個“订阅”按钮:
routes/web.php
Route::get('/subscribe', function () { return view('subscribe'); });
resources/views/subscribe.blade.php
<form action="/subscribe" method="POST"> @csrf <button>訂閱</button> </form>
Inertia.js 可以参考以下:
routes/web.php
Route::get('/subscribe', function () { return Inertia::render('Subscribe', [ 'csrfToken' => csrf_token(), ]); });
resources/js/pages/Subscribe.vue
<template> <form action="/subscribe" method="POST"> <input type="hidden" name="_token" :value="csrfToken"> <button>訂閱</button> </form> </template> <script setup> defineProps({ csrfToken: String, }) </script>
然后建立发送付款的路由:
use Ycs77\NewebPay\Facades\NewebPay; Route::post('/subscribe', function () { $no = now()->timestamp; // 訂單編號 $amt = 120; // 交易金額 $desc = '我的訂閱制商品'; // 商品名稱 $email = 'test@example.com'; // 付款人信箱 return NewebPay::period($no, $amt, $desc, $email) ->everyFewDays(2) ->times(3) ->submit(); });
建立委托请求返回结果
设置建立委托完成后,将页面导向回原本的网站页面:
use Illuminate\Http\Request; use Ycs77\NewebPay\Facades\NewebPay; Route::post('/pay/period/callback', function (Request $request) { $result = NewebPay::periodResult($request); if ($result->isFail()) { return redirect()->to('/pay')->with('error', $result->message()); } return redirect()->to('/pay')->with('success', '付款成功'); });
以及设置每期委托授权结果通知:
use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; use Ycs77\NewebPay\Facades\NewebPay; Route::post('/pay/period/notify', function (Request $request) { $result = NewebPay::periodNotify($request); if ($result->isFail()) { Log::error('藍新金流 定期定額 定期交易錯誤', $result->data()); return; } // 委託授權成功,處裡訂單邏輯... });
设置好之后可以在 config/newebpay.php 中设置网址:
return [ 'period' => [ // 建立委託完成後導向頁面 'return_url' => '/pay/period/callback', // 每期委託授權結果通知: 'notify_url' => '/pay/period/notify', ], ]
记得要把这些路径排除 CSRF 检查:
app/Http/Middleware/VerifyCsrfToken.php
class VerifyCsrfToken extends Middleware { protected $except = [ ... '/pay/period/callback', '/pay/period/notify', ]; }
授权周期
如果于周期内需要授权多次,请以建立多次委托方式执行。
设置此委托于固定天期制授权,输入数字为间隔天数 2~999。以授权日期起算,以下为每隔 40 天授权一次:
NewebPay::period($no, $amt, $desc, $email) ->everyFewDays(40) ->times(1) ->submit();
设置此委托于每周授权,输入数字为 1~7,代表每周一至周日。以下为每周日授权一次:
NewebPay::period($no, $amt, $desc, $email) ->weekly(7) ->times(1) ->submit();
设置此委托于每月授权,输入数字为 1~31,每月的第几天执行委托,若当月没有该日期则由该月最后一天做扣款日。以下为每月 20 日授权一次:
NewebPay::period($no, $amt, $desc, $email) ->monthly(20) ->times(1) ->submit();
设置此委托于每年授权,输入每年的几月几日执行委托。以下为每年 3 月 4 日授权一次:
NewebPay::period($no, $amt, $desc, $email) ->yearly(3, 4) ->times(1) ->submit();
授权期数
设置授权委托的期数。以下为每月 4 日授权,共授权 6 次,为期 6 个月:
NewebPay::period($no, $amt, $desc, $email) ->monthly(4) ->times(6) ->submit();
立即执行十元授权
设置立即执行十元授权,以验证信用卡:
'period' => [ 'start_type' => PeriodStartType::TEN_DOLLARS_NOW, ],
立即执行委托金额授权
设置立即执行委托金额授权:
'period' => [ 'start_type' => PeriodStartType::AUTHORIZE_NOW, ],
不检查信用卡信息,不授权
设置刷卡完成后,不检查信用卡信息,也不执行授权:
'period' => [ 'start_type' => PeriodStartType::NO_AUTHORIZE, ],
但需要设置首期授权日:
NewebPay::period($no, $amt, $desc, $email) ->everyFewDays(2) ->times(3) ->firstdate(2023, 3, 1) ->submit();
修改委托状态
修改委托状态需要传入订单编号、委托单号和委托状态:
use Illuminate\Http\Request; use Ycs77\NewebPay\Enums\PeriodStatus; use Ycs77\NewebPay\Facades\NewebPay; Route::post('/pay/period/status', function (Request $request) { $result = NewebPay::periodStatus($request->input('no'), $request->input('periodNo'), PeriodStatus::TERMINATE) ->submit(); return $result->isSuccess() ? back()->with('success', '修改委託狀態成功') : back()->withErrors(['no' => $result->message()]); });
委托状态可以修改成 PeriodStatus::SUSPEND
(暂停) 和 PeriodStatus::TERMINATE
(终止) 两种状态,设置成暂停之后还可以改成 PeriodStatus::RESTART
(启用),但只要终止委托后就无法再次启用了。
暂停后再次启用的委托将于最近一期开始授权。委托暂停后再次启用总期数不变,扣款时间将向后展延至期数满期。
修改委托内容
修改委托内容需要传入订单编号、委托单号,和设置要修改成的委托触发周期和授权次数:
use Illuminate\Http\Request; use Ycs77\NewebPay\Facades\NewebPay; Route::post('/pay/period/amt', function (Request $request) { $result = NewebPay::periodAmt($request->input('no'), $request->input('periodNo'), $request->input('amt')) ->everyFewDays(3) ->times(10) ->submit(); return $result->isSuccess() ? back()->with('success', '修改委託內容成功') : back()->withErrors(['no' => $result->message()]); });
参考
赞助
如果我所维护的套件帮助到你,可以考虑赞助我~ 我会非常感谢你~ 而且还可以显示您的大头贴在我的主要项目中。
许可
在 MIT LICENSE 下