Laravel,Lumen,ThinkPHP,Hyperf 项目里集成微信,支付宝

介绍

看标题都知道是干啥的,不要扭扭捏捏了,直接进入吧

支付宝能力
action说明返回值
web网页支付Response
appAPP支付Response
h5H5支付Response
scan二维码支付Collection
posPOS刷卡支付Collection
mini小程序支付Collection
transfer账户转账支付(暂时不考虑,场景太少)Collection
微信能力
action说明返回值
mp公众号支付Collection
appAPP支付Collection
h5H5支付Collection
scan二维码支付Collection
posPOS刷卡支付Collection
mini小程序支付Collection
transfer账户转账支付(暂时不考虑,场景太少)Collection

开搞

1:使用 composer 下载安装支付扩展包

#laravel,lumen,hyperf 安装方式

composer require yansongda/pay:~3.7.0 -vvv 

#无框架或者其他框架安装方式

composer require yansongda/pay:~3.7.0 -vvv
composer require guzzlehttp/guzzle:^7.0    #其他框架如果有此插件,可以不用安装
composer require hyperf/pimple:~2.2.0      #主要是 Container  复用

注意:
如果使用的框架内有符合 PSR-11 的 Container,需要在初始化之前,先调用以下代码以复用 Container,进行服务注入

<?php

use Yansongda\Pay\Pay;
use Yansongda\Pay\Contract\HttpClientInterface;

// $container = 您现有的 container

// 方法一:
Pay::setContainer($container);
Pay::config($config);

// 方法二:
Pay::config($config, function () use ($container) {
    return $container;
});

2:初始化支付参数

1:在 config 文件夹下新建 alipay.php 文件 (laravel框架,其他的自行找地方配置吧,能取出就行)

<?php

return [
    'alipay' => [
        'default' => [
            // 必填-支付宝分配的 app_id
            'app_id' => 'xxxxxxx',
            // 必填-应用私钥 字符串或路径
            // 在 https://open.alipay.com/develop/manage 《应用详情->开发设置->接口加签方式》中设置
            'app_secret_cert' => 'xxxxxx',
            // 必填-应用公钥证书 路径
            // 设置应用私钥后,即可下载得到以下3个证书
            'app_public_cert_path' => '/xxxx/appCertPublicKey_2016082000295641.crt',
            // 必填-支付宝公钥证书 路径
            'alipay_public_cert_path' => '/xxxx/alipayCertPublicKey_RSA2.crt',
            // 必填-支付宝根证书 路径
            'alipay_root_cert_path' => '/xxxx/alipayRootCert.crt',
            'return_url' => 'https://xxxxx',//同步返回地址
            'notify_url' => 'https://xxxxx',//异步回调地址
            // 选填-第三方应用授权token
            'app_auth_token' => '',
            // 选填-服务商模式下的服务商 id,当 mode 为 Pay::MODE_SERVICE 时使用该参数
            'service_provider_id' => '',
            // 选填-默认为正常模式。可选为: MODE_NORMAL, MODE_SANDBOX, MODE_SERVICE
            'mode' => 'MODE_NORMAL',
        ]
    ],
    'logger' => [ //日志模块,也可以在  logging.php 里自定义 channel 进行手动日志搜集
        'enable' => false,
        'file' => storage_path('logs/alipay.log'),
        'level' => 'info', 
        'type' => 'daily', 
        'max_file' => 10,
    ],
    'http' => [ 
        'timeout' => 5.0,
        'connect_timeout' => 5.0,
    ],

];

2:在 config 文件夹下新建 wechat.php 文件 (laravel框架,其他的自行找地方配置吧,能取出就行)

<?php

return [
    'wechat' => [
        'default' => [
            // 必填-商户号,服务商模式下为服务商商户号
            // 可在 https://pay.weixin.qq.com/ 账户中心->商户信息 查看
            'mch_id' => '',
            // 选填-v2商户私钥
            'mch_secret_key_v2' => '',
            // 必填-v3 商户秘钥
            // 即 API v3 密钥(32字节,形如md5值),可在 账户中心->API安全 中设置
            'mch_secret_key' => '',
            // 必填-商户私钥 字符串或路径
            // 即 API证书 PRIVATE KEY,可在 账户中心->API安全->申请API证书 里获得
            // 文件名形如:apiclient_key.pem
            'mch_secret_cert' => '',
            // 必填-商户公钥证书路径
            // 即 API证书 CERTIFICATE,可在 账户中心->API安全->申请API证书 里获得
            // 文件名形如:apiclient_cert.pem
            'mch_public_cert_path' => '',
            // 必填-微信回调url
            // 不能有参数,如?号,空格等,否则会无法正确回调
            'notify_url' => 'https://xxxx',
            // 选填-公众号 的 app_id
            // 可在 mp.weixin.qq.com 设置与开发->基本配置->开发者ID(AppID) 查看
            'mp_app_id' => 'xxxxx',
            // 选填-小程序 的 app_id
            'mini_app_id' => '',
            // 选填-小程序的 app_secret
            'mini_app_secret' => '',
            // 选填-app 的 app_id
            'app_id' => '',
            // 选填-服务商模式下,子公众号 的 app_id
            'sub_mp_app_id' => '',
            // 选填-服务商模式下,子 app 的 app_id
            'sub_app_id' => '',
            // 选填-服务商模式下,子小程序 的 app_id
            'sub_mini_app_id' => '',
            // 选填-服务商模式下,子商户id
            'sub_mch_id' => '',
            // 选填-微信平台公钥证书路径, optional,强烈建议 php-fpm 模式下配置此参数
            'wechat_public_cert_path' => [
                '45F59D4DABF31918AFCEC556D5D2C6E376675D57' => __DIR__.'/Cert/wechatPublicKey.crt',
            ],
            // 选填-默认为正常模式。可选为: MODE_NORMAL, MODE_SERVICE
            'mode' => 'MODE_NORMAL',
            //小程序授权登录,通过code换取openid和sessionkey的接口
            'jscode2session_url'=> 'https://api.weixin.qq.com/sns/jscode2session',
            //小程序通过sessionkey和其他加密参数解析获取手机号的接口
            'decrypt_phone_url'=> 'https://api.weixin.qq.com/wxa/business/getuserphonenumber',
        ]
    ],
    
    'logger' => [
        'enable' => false,
        'file' => storage_path('logs/wechat.log'),
        'level' => 'info', 
        'type' => 'daily', 
        'max_file' => 10, 
    ],
    'http' => [ // optional
        'timeout' => 5.0,
        'connect_timeout' => 5.0,
    ]

];

3:开始接入支付----支付宝

1:例如,我的订单信息为:

	$order = [
		"out_trade_no" => "1234567890",  #你自己的业务订单号
		"total_amount" => 1200,    #订单金额,单位 分
		"order_name" => "汤臣一品5号楼12层订单_小可爱",    #订单名称/描述
	]

2:在一个你喜欢的目录里封装一个类:例如 app/Services/AlipayService.php

<?php
namespace App\Services;

use App\Common\Functions;
use Illuminate\Support\Facades\Redis;
use Yansongda\Pay\Pay;

class AlipayService
{
	//网页网站支付
	public static function webPay($order){

		Pay::config(Config('alipay'));
		
		$data = Pay::alipay()->web([
			'out_trade_no' => $order['out_trade_no'],
			'total_amount' => $order['total_amount']/100,
			'subject' => $order['order_name'],
		]);

		return $data;

		// 获取跳转代码(表单形式)  return (string) $data->getBody();
	}

	//h5支付
	public static function h5Pay($order){

		Pay::config(Config('alipay'));

		return Pay::alipay()->h5([
		    'out_trade_no' => $order['out_trade_no'],
		    'total_amount' => $order['total_amount']/100,
		    'subject' => $order['order_name'],
		    'quit_url' => 'https://xxxxxx',
		 ]);

	}

	//app支付
	public static function appPay($order){

		Pay::config(Config('alipay'));

		return Pay::alipay()->app([
		    'out_trade_no' => $order['out_trade_no'],
		    'total_amount' => $order['total_amount']/100,
		    'subject' => $order['order_name'],
		 ]);

	}

	//小程序支付
	public static function miniPay($order){

		Pay::config(Config('alipay'));

		$result = Pay::alipay()->mini([
		    'out_trade_no' => $order['out_trade_no'],
		    'total_amount' => $order['total_amount']/100,
		    'subject' => $order['order_name'],
		    'buyer_id' => '1111223232323', #当前购买用户在此小程序下的id
		]);

		return $result->get('trade_no');  // 支付宝交易号
	}

	//pos支付
	public static function posPay($order){

		Pay::config(Config('alipay'));

		$result = Pay::alipay()->pos([
		    'out_trade_no' => $order['out_trade_no'],
		    'auth_code' => 'xxxxxxx', #授权code码
		    'total_amount' => $order['total_amount']/100,
		    'subject' => $order['order_name']
		]);

		return $result;
	}

	//扫码支付
	public static function scanPay($order){

		Pay::config(Config('alipay'));

		$result = Pay::alipay()->pos([
		    'out_trade_no' => $order['out_trade_no'],
		    'total_amount' => $order['total_amount']/100,
		    'subject' => $order['order_name']
		]);

		return $result->qr_code; // 二维码 url,前端直接渲染出来就可以
	}

	//查询订单
	public static function findOrder($outTradeNo, $type){

		if (!in_array($type, ['web','app','h5','scan','pos','mini'])) {
			return false;
		}

		Pay::config(Config('alipay'));
		
		$result = Pay::alipay()->query([
			'out_trade_no' => $outTradeNo,
			'_action' => $type
		]);

		return $result;

	}
	
	//查询退款订单
	public static function findRefundOrder($outTradeNo,$outRequestNo, $type){

		if (!in_array($type, ['web','app','h5','scan','pos','mini'])) {
			return false;
		}
		Pay::config(Config('alipay'));
		
		$result = Pay::alipay()->query([
			'out_trade_no' => $outTradeNo,
			'out_request_no' => $outRequestNo,
			'_action' => 'redund_'.$type
		]);

		return $result;

	}
	
	//退款
	public static function refundOrder($outTradeNo, $type){

		if (!in_array($type, ['web','app','h5','scan','pos','mini'])) {
			return false;
		}

		Pay::config(Config('alipay'));
		
		$result = Pay::alipay()->refund([
			'out_trade_no' => $outTradeNo,
			'refund_amount' => '0.01',
			'_action' => 'redund_'.$type
		]);

		return $result;

	}


}

3:支付宝回调

	public function alipayNotify(Request $request){

        Pay::config(Config('alipay'));

        $result =  Pay::alipay()->callback();
        //然后你就开始处理result结果吧,并处理你得业务逻辑
    }

4:开始接入支付---- 微信

1:例如,我的订单信息为:

	$order = [
		"out_trade_no" => "1234567890",  #你自己的业务订单号
		"total_amount" => 1200,    #订单金额,单位 分
		"order_name" => "后海四合院一套_大可爱",    #订单名称/描述
	]

2:在一个你喜欢的目录里封装一个类:例如 app/Services/WechatService.php

<?php
namespace App\Services;

use App\Common\Functions;
use Illuminate\Support\Facades\Redis;
use Yansongda\Pay\Pay;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Http;


class WechatService
{

	//公众号支付
	public static function mpPay($order){

		Pay::config(Config('wechat'));

		$payOrder = [
		    'out_trade_no' => $order['out_trade_no'], 
		    'description' => $order['order_name'],
		    'amount' => [
		        'total' => int($order['total_amount']),
		    ],
		    'payer' => [
		    	//这个是微信用户在此公众号下的唯一标识openid,可以通过微信支付官方文档获取https://pay.weixin.qq.com/docs/partner/development/glossary/parameter.html
		        'openid' => 'onkVf1FjWS5SBxxxxxxxx',
		    ],
		];

		$result = Pay::wechat()->mp($payOrder);
		// 返回 Collection 实例。包含了调用 JSAPI 的所有参数,如appId,timeStamp,nonceStr,package,signType,paySign 等;
		// 可直接通过 $result->appId, $result->timeStamp 获取相关值
		
	}

	//h5支付
	public static function h5Pay($order){

		Pay::config(Config('wechat'));

		$payOrder = [
			//'_type' => 'mini', // 如果关联的小程序appid,需要加上这一行;关联的公众号的则不需要
		    'out_trade_no' => $order['out_trade_no'],
		    'description' => $order['order_name'],
		    'amount' => [
		        'total' => $order['total_amount'],
		    ],
		    'scene_info' => [
		        'payer_client_ip' => '',
		        'h5_info' => [
		            'type' => 'Wap',
		        ]
		    ],
		];
		return Pay::wechat()->h5($payOrder);

	}

	//app支付
	public static function appPay($order){

		Pay::config(Config('wechat'));

		$payOrder = [
		    'out_trade_no' => $order['out_trade_no'],
		    'description' => $order['order_name'],
		    'amount' => [
		        'total' => $order['total_amount'],
		    ],
		];
		return Pay::wechat()->app($payOrder);
	}

	//小程序支付
	public static function miniPay($order){

		Pay::config(Config('wechat'));

		$payOrder = [
		    'out_trade_no' => $order['out_trade_no'],
		    'description' => $order['order_name'],
		    'amount' => [
		        'total' => $order['total_amount'],
		        'currency' => 'CNY',
		    ],
		    'payer' => [
		        'openid' => '123fsdf234', //用户在小程序下的openid,下面有获取的方法,decryptMiniCode
		    ]
		];
		$result = Pay::wechat()->mini($payOrder);
		// 返回 Collection 实例。包含了调用JSAPI的所有参数,如appId,timeStamp,nonceStr,package,signType,paySign 等;
		// 可直接通过 $result->appId, $result->timeStamp 获取相关值。
	}


	//扫码支付
	public static function scanPay($order){

		Pay::config(Config('wechat'));

		$payOrder = [
		    'out_trade_no' => $order['out_trade_no'],
		    'description' => $order['order_name'],
		    'amount' => [
		        'total' => $order['total_amount'],
		    ],
		];
		$result = Pay::wechat()->scan($payOrder);
		return $result->code_url; // 二维码内容
	}


	/**
	 * 查询订单
	 */
	public static function findOrder($outTradeNo = '', $type){

		if (!in_array($type,['jsapi','app','combine','h5','miniapp','native'])) {
			return false;
		}

		Pay::config(Config('wechat'));

		$result = Pay::wechat()->query([
			'out_trade_no' => $outTradeNo,
			'_action' => $type
		]);
		return $result;

	}
	
	//订单退款
	public static function refundOrder($orderTradeNo, $type, $refundId = ''){

		if (!in_array($type,['jsapi','app','combine','h5','miniapp','native'])) {
			return false;
		}

		Pay::config(Config('wechat'));

		$result = Pay::wechat()->refund([
			'out_trade_no' => $orderTradeNo,
			'out_refund_no' => $refundId ?? 'refund_wechat_id_'.time(),
			'amount' => [
				'refund' => 1,
				'total' => 1,
				'currency' => 'CNY'
			],
			'_action' => $type 
		]);

		return $result;

	}

	//小程序授权登录获取openid,seesion_key,文档链接:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html
	public static function decryptMiniCode($code){

		$config = Config('wechat')['wechat']['default'];

		$result = Http::asForm()->post($config['jscode2session_url'],[
			'appid' => $config['mini_app_id'],
			'secret' => $config['mini_app_secret'],
			'js_code' => $code, //登录时获取的 code,可通过wx.login获取
			'grant_type' => 'authorization_code'
		]);
		return $result->successful() ? $result->json() : [];
	}

}

2:微信回调

public function wechatNotify(Request $request){

        Pay::config(Config('wechat'));

        $result =  Pay::wechat()->callback();
    }
  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值