<?php
declare (strict_types = 1);

namespace app\api\controller;

use EasyWeChat\Pay\Application;
use think\facade\Log;
use think\facade\Db;

class Pay
{
    private $wechatConfig;

    public function __construct()
    {
        $this->wechatConfig = [
            'mch_id' => '商户号',
            'private_key' => '/www/wwwroot/yitianclub/public/cert/apiclient_key.pem',
            'certificate' => '/www/wwwroot/yitianclub/public/cert/apiclient_cert.pem',
            'secret_key' => 'yitianclubcn20240522155088888888', // API v3 Key
            'http' => [
                'throw' => true,
                'timeout' => 5.0,
            ],
        ];
    }

    public function pay()
    {
        $orderNo = date('YmdHis') . uniqid();
        $openid = "oOp7L6-cjRmDz90AcuPK9x3zJ5kU"; // 小程序下的用户openid
        $amount = 0.01; // 支付金额
        $appId = ""; // 小程序appId

        $data = [
            'openid' => $openid,
            'orderno' => $orderNo,
            'amount' => $amount,
        ];

        try {
            Db::table('demo_order')->save($data);

            $app = new Application($this->wechatConfig);
            $response = $app->getClient()->postJson("v3/pay/transactions/jsapi", [
                "mchid" => $this->wechatConfig['mch_id'],
                "out_trade_no" => $orderNo,
                "appid" => $appId, 
                "description" => "this is demo",
                "notify_url" => "", // 支付成功后回调通知URL
                "amount" => [
                    "total" => 1,
                    "currency" => "CNY",
                ],
                "payer" => [
                    "openid" => $openid,
                ],
            ]);

            $res = $response->toArray();
            if (!isset($res['prepay_id'])) {
                throw new \Exception('Failed to get prepay_id: ' . json_encode($res));
            }

            $prepayId = $res['prepay_id'];
            $utils = $app->getUtils();
            $signType = 'RSA';
            $config = $utils->buildMiniAppConfig($prepayId, $appId, $signType);

            return view('/pay/index', ['config' => $config]);

        } catch (\Exception $e) {
            Log::error('WeChat Pay Error: ' . $e->getMessage());
            return json(['error' => 'Payment processing failed. Please try again later.'], 500);
        }
    }

    public function notify()
    {
        $app = new Application($this->wechatConfig);
        $server = $app->getServer();

        try {
            $response = $server->handlePaid(function ($message) {
                if ($message['trade_state'] === 'SUCCESS') {
                    Db::table('demo_order')
                        ->where('orderno', '=', $message['out_trade_no'])
                        ->update(['status' => 1]);
                    Log::info('WeChat payment succeeded: ' . $message);
                } else {
                    Log::warning('WeChat payment failed or pending: ' . $message);
                }
            });

            return $response->serve();

        } catch (\Exception $e) {
            Log::error('WeChat Notify Error: ' . $e->getMessage());
            return response('Notification processing failed', 500);
        }
    }
}

更多推荐