自学内容网 自学内容网

微信支付开发-支付工厂H5Api退款代码

一、H5支付产品、Native支付产品

二、工厂父类抽象类代码开发

<?php
/**
 * 微信父类抽象类
 * User: 龙哥·三年风水
 * Date: 2024/9/19
 * Time: 11:33
 */
namespace Payment\WechatPay;
abstract class WechatPaymentHandle
{
    /**
     * 下单
     * User: 龙哥·三年风水
     * Date: 2024/9/19
     * Time: 11:36
     * @ return mixed
     */
    protected abstract function pay();

    /**
     * 查询
     * User: 龙哥·三年风水
     * Date: 2024/9/19
     * Time: 11:39
     * @ return mixed
     */
    protected abstract function transac();

    /**
     * 退款
     * User: 龙哥·三年风水
     * Date: 2024/9/19
     * Time: 11:42
     * @ return mixed
     */
    protected abstract function refunds();
}

三、工厂通道选择类代码开发

<?php
/**
 * 微信支付工厂通道选择类
 * User: 龙哥·三年风水
 * Date: 2024/9/19
 * Time: 11:47
 */
namespace Payment\WechatPay;
use app\BaseError;
use Payment\WechatPay\impl\AppApi;
use Payment\WechatPay\impl\Applet;
use Payment\WechatPay\impl\H5Api;
use Payment\WechatPay\impl\JsApi;
use Payment\WechatPay\impl\NativeApi;

class WechatPaymentFactory
{
    protected static $instance = null;//缓存实例
    protected $merchantId = null;// 商户号
    protected $merchantSerialNumber = null;// 商户API证书序列号
    protected $appid = null;// 公众号ID
    protected $merchantPrivateKey = null;// 商户私钥
    protected $channelType = 0;//通道类型

    /**
     * 初始化资源
     */

    public function __construct($type){
        $this->merchantId = config('pay.wechat.merchant_id');
        $this->appid = config('pay.wechat.app_id');
        $this->merchantSerialNumber = config('pay.wechat.merchant_serial_number');
        $file = file_get_contents('./wechatpay/apiclient_key.pem');
        $this->merchantPrivateKey = openssl_get_privatekey($file);// 读取商户秘钥
        self::$instance = null;
        $this->channelType = $type;
    }


    /**
     * 通道选择
     * User: 龙哥·三年风水
     * Date: 2024/9/19
     * Time: 14:34
     * @ param $url
     * @ param $data
     * @ return null|JsApi
     */

    public function sendWechatPaymentHandle($url,$data){
        switch ((int)$this->channelType){
            case 1:
                $data['appid'] = $this->appid;
                $data['mchid'] = $this->merchantId;
                $authorization = $this->getSign($url,$data);
                self::$instance = new JsApi($url,$authorization,$data);
                break;
            case 2:
                $data['appid'] = $this->appid;
                $data['mchid'] = $this->merchantId;
                $authorization = $this->getSign($url,$data);
                self::$instance = new AppApi($url,$authorization,$data);
                break;
            case 3:
                $data['appid'] = $this->appid;
                $data['mchid'] = $this->merchantId;
                $authorization = $this->getSign($url,$data);
                self::$instance = new H5Api($url,$authorization,$data);
                break;
            case 4:
                $data['appid'] = $this->appid;
                $data['mchid'] = $this->merchantId;
                $authorization = $this->getSign($url,$data);
                self::$instance = new NativeApi($url,$authorization,$data);
                break;
            case 5:
                $data['appid'] = $this->appid;
                $data['mchid'] = $this->merchantId;
                $authorization = $this->getSign($url,$data);
                self::$instance = new Applet($url,$authorization,$data);
                break;
            default:
                self::$instance = null;
                throw new BaseError("未设置任何通道",50000,200);
                break;
        }
        return self::$instance;
    }

    /**
     * 生成签名
     * User: 龙哥·三年风水
     * Date: 2024/9/19
     * Time: 14:01
     * @ param $url
     * @ param $data
     * @ return string
     */

    protected function getSign($url,$data){
        $timestamp = time();
        $nonce = alnum(12).date('YmdHis', $timestamp) . rand(1000, 9999);
        $url_parts = parse_url($url);
        $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
        $data = json_encode($data);
        $message = 'POST' . "\n" .
            $canonical_url . "\n" .
            $timestamp . "\n" .
            $nonce . "\n" .
            $data . "\n";
        openssl_sign($message, $signature, $this->merchantPrivateKey, "sha256WithRSAEncryption");
        $sign = base64_encode($signature);
        $schema = 'WECHATPAY2-SHA256-RSA2048';
        $token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',  $this->merchantId, $nonce, $timestamp, $this->merchantSerialNumber, $sign);
        return "Authorization: " . $schema . " " . $token;
    }

    /**
     *销毁资源
     */

    public function __destruct(){
        $this->merchantId = null;
        $this->appid = null;
        $this->merchantSerialNumber = null;
        $this->merchantPrivateKey = null;
        self::$instance = null;
    }
}

四、H5支付产品代码开发

<?php
/**
 * H5支付方式
 * User: 龙哥·三年风水
 * Date: 2024/9/20
 * Time: 11:29
 */
namespace Payment\WechatPay\impl;
use Payment\WechatPay\WechatPaymentHandle;
use app\BaseError;
class H5Api extends WechatPaymentHandle
{
    protected $url = ''; //访问路径
    protected $header = ''; //头文件
    protected $data = []; //数据组

    /**
     * 初始化
     * @ param $url
     * @ param $header
     * @ param $data
     */

    public function __construct($url,$header,$data){
        $this->url = $url;
        $this->header = $header;
        $this->data = $data;
    }

    /**
     * 下单
     * User: 龙哥·三年风水
     * Date: 2024/9/19
     * Time: 11:36
     * @ return mixed
     */
    public function pay()
    {
        $res = http_post($this->url, $this->header, $this->data);
        $arr = json_decode($res, true);
        if(isset($arr['code'])) {
            $error['code'] = $arr['code'];
            $error['message'] = $arr['message'];
            $error['timestamp'] = time();
            $error['ip'] = get_client_ip();
            file_put_contents('h5_pay.txt', json_encode($error) . PHP_EOL, FILE_APPEND);
            throw new BaseError($arr['message'], 50000, 200);
        }
        return $arr;
    }

    /**
     * 查询
     * User: 龙哥·三年风水
     * Date: 2024/9/19
     * Time: 11:39
     * @ return mixed
     */
    public function transac()
    {
        // TODO: Implement transac() method.
    }

    /**
     * 退款
     * User: 龙哥·三年风水
     * Date: 2024/9/19
     * Time: 11:42
     * @ return mixed
     */
    public function refunds()
    {
        $res = http_post($this->url, $this->header, $this->data);
        $arr = json_decode($res, true);
        if(isset($arr['code'])) {
            $error['code'] = $arr['code'];
            $error['message'] = $arr['message'];
            $error['timestamp'] = time();
            $error['ip'] = get_client_ip();
            file_put_contents('h5_pay.txt', json_encode($error) . PHP_EOL, FILE_APPEND);
            throw new BaseError($arr['message'], 50000, 200);
        }
        return $arr;
    }

    /**
     *
     */

    public function __destruct(){
        $this->url = '';
        $this->header = '';
        $this->data = [];
    }
}

五、测试调用

public function index(){
        //定义参数
        $data['out_trade_no'] = '老订单号'; //原支付交易对应的微信订单号,与out_trade_no二选一
        $data['transaction_id'] = '老微信支付单号'; //原支付交易对应的商户订单号,与transaction_id二选一
        $data['out_refund_no'] = create_order(); //退款单号
        $data['notify_url'] = 'http://www.baidu.com'; //异步接收微信支付退款结果通知的回调地址
        $data['amount'] = [
            'refund'    =>  100, //退款金额,单位为分,只能为整数,不能超过原订单支付金额。
            'total'     =>  100, //原支付交易的订单总金额,单位为分,只能为整数。
            'currency'  =>  'CNY' //符合ISO 4217标准的三位字母代码,目前只支持人民币:CNY。
        ];
        // 初始化通道
        $wechatPaymentFactory = new WechatPaymentFactory(3);
        // 选择实例
        $wechatPaymentHandle = $wechatPaymentFactory->sendWechatPaymentHandle('https://api.mch.weixin.qq.com/v3/refund/domestic/refunds',$data);
        $res = $wechatPaymentHandle->pay();
        var_dump($res);
}

原文地址:https://blog.csdn.net/m0_63603104/article/details/142452092

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!