以JSAPI支付为例
一、参照文档引入 composer 包 overtrue/laravel-wechat
二、商户开发配置自行到微信官网获取 商户后台
三、具体代码如下
<?php
namespace App\Http\Controllers\H5\Verification;
use EasyWeChat\Factory;
use App\Model\Agent\Agent;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Model\Advert\PlatformConfig;
use App\Model\OfflineClassroom\ClassroomAppiesModel;
use App\Model\OfflineClassroom\ClassroomPayHistoryModel;
use App\Model\OfflineClassroom\ClassroomRefundHistoryModel;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use function EasyWeChat\Kernel\Support\generate_sign;
class PayController extends Controller
{
protected $request;
protected $agent;
protected $appiesModel;
protected $platformConfig;
protected $historyModel;
protected $refundHistoryModel;
public function __construct(Request $request, Agent $agent, ClassroomAppiesModel $appiesModel, PlatformConfig $platformConfig, ClassroomPayHistoryModel $historyModel, ClassroomRefundHistoryModel $refundHistoryModel)
{
parent::__construct($request);
$this->request = $request;
$this->agent = $agent;
$this->appiesModel = $appiesModel;
$this->platformConfig = $platformConfig;
$this->historyModel = $historyModel;
$this->refundHistoryModel = $refundHistoryModel;
}
public function config()
{
$server = $this->request->server();
return [
'app_id' => env('WECHAT_OFFICIAL_ACCOUNT_APPID', 'wx0b019484714*****'),
'mch_id' => env('WECHAT_MCH_ID', '******'),
'key' => env('WECHAT_API_SECRET_KEY', 'p32u23u4jk5l******8sdf378sjdf'),
'cert_path' => $server['DOCUMENT_ROOT'] . '/wxpay/apiclient_cert.pem',
'key_path' => $server['DOCUMENT_ROOT'] . '/wxpay/apiclient_key.pem',
'notify_url' => env('APP_URL', 'https://lhdev.com') . '/mapi/wechat_pay_notify',
];
}
public function wechat_pay()
{
$order_no = request('order_no');
if (empty($order_no)) {
return restful(['message' => '订单编号不能为空', 'code' => 201]);
}
$data = $this->get_data();
if ($data['code'] == 201) {
return restful($data);
}
$app = Factory::payment($this->config());
$result = $app->order->unify([
'body' => '课程押金',
'out_trade_no' => $order_no,
'total_fee' => $data['total_fee'],
'trade_type' => 'JSAPI',
'openid' => $data['openid'],
]);
if ($result['return_code'] === 'SUCCESS' && !empty($result['prepay_id'])) {
$params = [
'appId' => $result['appid'],
'timeStamp' => time(),
'nonceStr' => $result['nonce_str'],
'package' => 'prepay_id=' . $result['prepay_id'],
'signType' => 'MD5',
];
$params['paySign'] = generate_sign($params, $this->config()['key']);
return restful(['message' => 'OK', 'data' => $params]);
} else {
return restful(['message' => '错误', 'data' => $result, 'code' => 201]);
}
}
public function wechat_pay_notify()
{
try {
DB::beginTransaction();
$app = Factory::payment($this->config());
$response = $app->handlePaidNotify(function ($message, $fail) {
$order = $this->appiesModel->where(['order_no' => $message['out_trade_no']])->first();
if (!$order || $order->pay_at) {
return true;
}
if ($message['return_code'] === 'SUCCESS') {
if ($message['result_code'] === 'SUCCESS') {
$order->pay_status = 1;
$order->amount = $message['total_fee'];
$order->pay_at = date('Y-m-d H:i:s');
} elseif ($message['result_code'] === 'FAIL') {
$order->pay_status = 4;
}
} else {
return true;
}
$order->save();
$this->payment_history($message, $order->agent_id);
DB::commit();
return true;
});
$response->send();
} catch (\Exception $e) {
DB::rollBack();
return false;
}
}
public function check_pay_results()
{
$order_no = request('order_no');
if (empty($order_no)) {
return restful(['message' => '订单编号不能为空', 'code' => 201]);
}
$app = Factory::payment($this->config());
$result = $app->order->queryByOutTradeNumber($order_no);
if ($result['result_code'] === 'SUCCESS') {
return restful(['message' => '支付成功', 'data' => $result]);
}
return restful(['message' => '支付失败', 'data' => $result, 'code' => 201]);
}
public function get_data()
{
$agent_id = resolve('agent')['id'];
$agent = $this->agent->where('id', $agent_id)->first(['id', 'weixin_openid']);
if (empty($agent->weixin_openid)) {
return ['message' => '微信未授权无法支付', 'code' => 201];
}
$data = $this->platformConfig->first(['id', 'deposit']);
$total_fee = $data ? bcmul($data->deposit, 100) : 100;
return [
'code' => 200,
'openid' => $agent->weixin_openid,
'total_fee' => (int)$total_fee
];
}
public function payment_history($data = [], $agent_id)
{
$time = time();
$payment = [
'agent_id' => $agent_id,
'trade_type' => $data['trade_type'],
'transaction_id' => $data['transaction_id'],
'order_no' => $data['out_trade_no'],
'total_fee' => $data['total_fee'],
'info' => json_encode($data),
'created_at' => $time,
'updated_at' => $time,
];
$this->historyModel->create($payment);
}
public function refund()
{
$id = request('id');
if (empty($id)) {
return ['message' => '参数错误', 'code' => 201];
}
$order = $this->appiesModel->with(['history'])->find($id);
if (empty($order)) {
return ['message' => '报名记录不存在', 'code' => 201];
}
if ($order->pay_status != 1) {
return ['message' => '支付状态错误不可退款(未支付或已退款)', 'code' => 201];
}
if (empty($order->history)) {
return ['message' => '没有支付记录退款失败', 'code' => 201];
}
if (empty($order->amount)) {
return ['message' => '金额有误退款失败', 'code' => 201];
}
$data = $order->toArray()['history'];
$refund_no = 'TK' . time() . mt_rand(10000, 99999);
$other['refund_desc'] = '押金退还';
$other['notify_url'] = env('APP_URL', 'https://lhdev.com') . '/mapi/wechat_funded_notify';
$app = Factory::payment($this->config());
$result = $app->refund->byTransactionId($data['transaction_id'], $refund_no, $data['total_fee'], $data['total_fee'], $other);
if ($result['return_code'] === 'SUCCESS' && !empty($result['out_trade_no'])) {
$this->appiesModel->where(['order_no' => $result['out_trade_no']])->update(['pay_status' => 3]);
return ['message' => '操作成功', 'data' => $result];
}
return ['message' => $result['err_code_des'], 'data' => $result, 'code' => 201];
}
public function wechat_funded_notify()
{
$app = Factory::payment($this->config());
$response = $app->handleRefundedNotify(function ($message, $reqInfo, $fail) {
return $this->refund_history($reqInfo);
});
$response->send();
}
public function refund_history($data = [])
{
try {
DB::beginTransaction();
if (!empty($data) && $data['refund_status'] === 'SUCCESS') {
$up_data = ['pay_status' => 2, 'refund_at' => date('Y-m-d H:i:s')];
$this->appiesModel->where(['order_no' => $data['out_trade_no']])->update($up_data);
$time = time();
$refund = [
'refund_id' => $data['refund_id'],
'refund_no' => $data['out_refund_no'],
'transaction_id' => $data['transaction_id'],
'order_no' => $data['out_trade_no'],
'total_fee' => $data['total_fee'],
'refund_fee' => $data['refund_fee'],
'info' => json_encode($data),
'created_at' => $time,
'updated_at' => $time,
];
$this->refundHistoryModel->create($refund);
DB::commit();
return true;
}
} catch (\Exception $e) {
DB::rollBack();
return false;
}
}
}
四、更多内容请参考EasyWeChat官方文档
|