php实现支付宝在线支付和扫码支付demo

时间:2021-10-13 21:58:26

php实现支付宝在线支付和扫码支付demo


背景:在做一个公众号时增加了h5端,需要接入支付,非微信环境,选择了支付宝,以下简单记录下实现过程,并做了简单的封装,拿来即可使用,注意:本项目只是基于官方demo修改的,需要接入自己项目的需要按需获取到。

demo的github地址:https://github.com/alisleepy/alipay

目录结构:

以下的文件目录无需修改,只修改config.php配置文件和paytest.php和create_qrcode.php文件

/aop                       //核心库
/img //二维码中心的icon(自己引入的)
/lib //核心库
/lotusphp_runtime //没用到
/phpqrcode //生成二维码的插件(扫码支付时自己引入的,没用官方的)
/service //官方demo的测试文件(没用到)
AopSdk.php //demo项目入口文件,不用修改
config.php //重要,存放配置文件
create_qrcode.php //二维码扫码支付demo
notify_url.php //异步回调地址(只测试了支付,没用到)
paytest.php //在线支付demo
return_url.php //同步跳转地址(没用到)

步骤:

  1. 申请支付宝开发者
  2. 创建沙箱应用,获取到appId
  3. 获取公钥秘钥等信息,修改config.php
  4. 修改文件实现支付功能

在线支付代码:paytest.php

<?php
/**
* 功能:支付宝支付测试文件
* 版本:v1.0
* author:wangkk
* 以下部分就是具体的支付过程,只需要引入自己的配置文件$config数组信息,同时需要获取订单信息即可使用
*/ //引入sdk文件
require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'aop/AopClient.php';
require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'aop/request/AlipayTradeWapPayRequest.php';
//引入配置文件信息
require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'config.php'; /**
* 支付宝支付类的封装
*/
class Alipay{
//配置文件数据
public $alipay_config;
//构造函数,获取数据
public function __construct($alipay_config){
//配置项
$this->gateway_url = $alipay_config['gatewayUrl'];
$this->appid = $alipay_config['app_id'];
$this->private_key = $alipay_config['merchant_private_key'];
$this->alipay_public_key = $alipay_config['alipay_public_key'];
$this->charset = $alipay_config['charset'];
$this->signtype = $alipay_config['sign_type'];
$this->notify_url = $alipay_config['notify_url'];
$this->return_url = $alipay_config['return_url']; if(empty($this->appid) || trim($this->appid) == ""){
throw new Exception("appid不能为空!");
}
if(empty($this->private_key) || trim($this->private_key) == ""){
throw new Exception("商户密钥不能为空!");
}
if(empty($this->alipay_public_key) || trim($this->alipay_public_key) == ""){
throw new Exception("商户公钥不能为空!");
}
if(empty($this->charset) || trim($this->charset)== "" ){
throw new Exception("编码格式不能为空");
}
if(empty($this->gateway_url) || trim($this->gateway_url) == ""){
throw new Exception("支付网关地址不能为空!");
}
if(empty($this->notify_url) || trim($this->notify_url) == ""){
throw new Exception("异步回调地址不能为空!");
}
} public function pay(){
//订单号,自定义,唯一
$out_trade_no = $_GET['out_trade_no']; /** --------------------------------以下部分需要修改:获取订单信息 start--------------------------------- **/
//通过订单号获取到订单信息
// $orderInfo = M('order')->where(['out_trade_no'=>$out_trade_no])->find();
// if(empty($orderInfo)){
// throw new Exception("查无此订单");
// }
// //参数列表
// $body = $orderInfo['body']; //商品描述,可为空
// $subject = $orderInfo['subject']; //订单标题,必填
// $out_trade_no = $orderInfo['out_trade_no']; //订单号,必填
// $total_amount = $orderInfo['total_amount']; //订单金额,必填
/** --------------------------------以上部分需要修改:获取订单信息 end--------------------------------- **/
//订单测试信息,真实项目把以下几行删除,使用上边的真实数据
$body = '商品描述'; //商品描述,可为空
$subject = '订单标题'; //订单标题,必填
$out_trade_no = rand(10000,99999); //订单号,必填
$total_amount = rand(1,5); //订单金额,必填 $timeout_express = '1m'; //超时,1分钟
$product_code = 'QUICK_WAP_WAY'; //手机端支付宝
if(empty($subject) || trim($subject) == ""){
throw new Exception("订单标题不能为空");
}
if(empty($total_amount) || trim($total_amount) == ""){
throw new Exception("订单金额不能为空");
} //组装订单数据
$bizContentarr = array(
'body' => $body ? $body : '', //商品描述,可以为空
'subject' => $subject,
'out_trade_no' => $out_trade_no,
'total_amount' => $total_amount,
'timeout_express' => $timeout_express,
'product_code' => $product_code,
);
$bizContent = json_encode($bizContentarr,JSON_UNESCAPED_UNICODE); //设置数据
$aopObj = new \AopClient();
$aopObj->gatewayUrl = $this->gateway_url;
$aopObj->appId = $this->appid;
$aopObj->rsaPrivateKey = $this->private_key;
$aopObj->alipayrsaPublicKey = $this->alipay_public_key;
$aopObj->apiVersion = '1.0';
$aopObj->postCharset = $this->charset;
$aopObj->format = 'json';
$aopObj->signType = $this->signtype; //设置请求的数据
$request = new \AlipayTradeWapPayRequest ();
$request->setBizContent($bizContent);
$request->setNotifyUrl($this->notify_url);
$request->setReturnUrl($this->return_url);
$result = $aopObj->pageExecute($request);
echo $result;
}
} //获取到配置文件,框架里的话直接放在配置文件中,通过框架方法去获取
$configInfo = $config;
$AlipayObj = new Alipay($configInfo);
$AlipayObj->pay();

扫码支付代码:create_qrcode.php

<?php
/**
* 功能:支付宝生成二维码
* 版本:v1.0
* author:wangkk
* 以下部分就是具体的生成二维码过程,只需要引入自己的配置文件$config数组信息,同时需要获取订单信息即可使用
*/ //引入sdk文件
require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'aop/AopClient.php';
require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'aop/request/AlipayTradePrecreateRequest.php';
//引入配置文件信息
require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'config.php';
//引入生成二维码的插件
require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'phpqrcode/phpqrcode.php'; class CreateQrcode{
public function __construct($alipay_config){
//配置项
$this->gateway_url = $alipay_config['gatewayUrl'];
$this->appid = $alipay_config['app_id'];
$this->private_key = $alipay_config['merchant_private_key'];
$this->alipay_public_key = $alipay_config['alipay_public_key'];
$this->charset = $alipay_config['charset'];
$this->signtype = $alipay_config['sign_type'];
$this->notify_url = $alipay_config['notify_url'];
$this->return_url = $alipay_config['return_url']; if(empty($this->appid) || trim($this->appid) == ""){
throw new Exception("appid不能为空!");
}
if(empty($this->private_key) || trim($this->private_key) == ""){
throw new Exception("商户密钥不能为空!");
}
if(empty($this->alipay_public_key) || trim($this->alipay_public_key) == ""){
throw new Exception("商户公钥不能为空!");
}
if(empty($this->charset) || trim($this->charset)== "" ){
throw new Exception("编码格式不能为空");
}
if(empty($this->gateway_url) || trim($this->gateway_url) == ""){
throw new Exception("支付网关地址不能为空!");
}
if(empty($this->notify_url) || trim($this->notify_url) == ""){
throw new Exception("异步回调地址不能为空!");
}
} //支付
public function pay(){
//订单号,自定义,唯一
$out_trade_no = $_GET['out_trade_no']; /** --------------------------------以下部分需要修改:获取订单信息 start--------------------------------- **/
//通过订单号获取到订单信息
// $orderInfo = M('order')->where(['out_trade_no'=>$out_trade_no])->find();
// if(empty($orderInfo)){
// throw new Exception("查无此订单");
// }
// //参数列表
// $body = $orderInfo['body']; //商品描述,可为空
// $subject = $orderInfo['subject']; //订单标题,必填
// $out_trade_no = $orderInfo['out_trade_no']; //订单号,必填
// $total_amount = $orderInfo['total_amount']; //订单金额,必填
/** --------------------------------以上部分需要修改:获取订单信息 end--------------------------------- **/
//订单测试信息,真实项目把以下几行删除,使用上边的真实数据
$body = '商品描述'; //商品描述,可为空
$subject = '订单标题'; //订单标题,必填
$out_trade_no = rand(10000,99999); //订单号,必填
$total_amount = rand(1,5); //订单金额,必填 $aopObj = new \AopClient ();
//设置值
$aopObj->gatewayUrl = $this->gateway_url;
$aopObj->appId = $this->appid;
$aopObj->rsaPrivateKey = $this->private_key;
$aopObj->alipayrsaPublicKey = $this->alipay_public_key;
$aopObj->apiVersion = '1.0';
$aopObj->postCharset = $this->charset;
$aopObj->format = 'json';
$aopObj->signType = $this->signtype; $request = new AlipayTradePrecreateRequest();
//组装订单数据
$timeout_express = '5m'; //超时,1分钟
$bizContentarr = array(
'body' => $body ? $body : '', //商品描述,可以为空
'subject' => $subject,
'out_trade_no' => $out_trade_no,
'total_amount' => $total_amount,
'timeout_express' => $timeout_express, //过期时间
);
$bizContent = json_encode($bizContentarr,JSON_UNESCAPED_UNICODE);
$request->setBizContent($bizContent);
$result = $aopObj->execute($request);
$responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
$resultCode = $result->$responseNode->code;
if(!empty($resultCode) && $resultCode == 10000){
//成功,得到二维码,在这不使用官方的方法,官方使用的是google的,墙内不ok
$qr_code_url = $result->$responseNode->qr_code;
$icon = './img/logo.png';//准备好的logo图片
\QRcode::png($qr_code_url,false, 'H', 4, false);
$code = ob_get_clean();
$code = imagecreatefromstring($code);
$logo = imagecreatefrompng($icon);
$QR_width = imagesx($code);//二维码图片宽度
$QR_height = imagesy($code);//二维码图片高度
$logo_width = imagesx($logo);//logo图片宽度
$logo_height = imagesy($logo);//logo图片高度
$logo_qr_width = $QR_width / 4;
$scale = $logo_width/$logo_qr_width;
$logo_qr_height = $logo_height/$scale;
$from_width = ($QR_width - $logo_qr_width) / 2;
//重新组合图片并调整大小
imagecopyresampled($code, $logo, $from_width, $from_width, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);
header ( "Content-type: image/png" );
ImagePng($code);
echo $qrcode;die;
} else {
echo 'fail';die;
}
}
}
$alipay_config = $config;
$CreateQrcodeObj = new CreateQrcode($alipay_config);
$CreateQrcodeObj->pay();

总结

终点就是获取公钥秘钥这部分一定不能错,还有就是在真实项目中的话按需引入sdk文件,但aop,lotusphp_runtime这两个文件夹是支付宝核心库,必须引入,AopSdk.php是入口文件,必须引入

php实现支付宝在线支付和扫码支付demo的更多相关文章

  1. ASP&period;NET Core 2&period;0 支付宝当面付之扫码支付

    前言 自从微软更换了CEO以后,微软的战略方向有了相当大的变化,不再是那么封闭,开源了许多东西,拥抱开源社区,.NET实现跨平台,收购xamarin并免费提供给开发者等等.我本人是很喜欢.net的,并 ...

  2. 支付宝支付之扫码支付(电脑网站支付)、H5支付(手机网站支付)相关业务流程分析总结

    前言 在上一篇文章<微信支付之扫码支付.公众号支付.H5支付.小程序支付相关业务流程分析总结>中,分析和总结了微信支付相关支付类型的业务流程,这里作为与微信支付平起平坐不相伯仲的支付宝支付 ...

  3. 微信原生支付 Native扫码支付&lpar; V3&period;3&period;7 版本&rpar;

    原文:微信原生支付 Native扫码支付( V3.3.7 版本) [尊重别人的劳动成果,转载请注明出处:一缕晨光工作室,www.wispdawn.com] 前言 辛苦研究三天,遇到各种困难,最终还是克 ...

  4. 微信公众号支付&vert;微信H5支付&vert;微信扫码支付&vert;小程序支付&vert;APP微信支付解决方案总结

    最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付.APP微信支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存. 先说注意 ...

  5. C&num;版微信公众号支付&vert;微信H5支付&vert;微信扫码支付问题汇总及解决方案总结

    最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存.代码在文章结尾处,有需要的 ...

  6. asp&period;net core 微信扫码支付(扫码支付,H5支付,公众号支付,app支付)之1

    2018-08-13更新生成二维码的方法 在做微信支付前,首先要了解你需要什么方式的微信支付,目前本人做过的支付包含扫码支付.H5支付.公众号支付.App支付等,本人使用的是asp.net mvc c ...

  7. 微信支付之扫码支付、公众号支付、H5支付、小程序支付相关业务流程分析总结

    前言 很久以来,一直想写一篇微信支付有关的总结文档:一方面是总结自己的一些心得,另一方面也可以帮助别人,但是因种种原因未能完全理解透彻微信支付的几大支付方式,今天有幸做一些总结上的文章,也趁此机会,将 ...

  8. Python实现支付宝当面付之——扫码支付

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7680348.html 一:配置信息准备 登录蚂蚁金服开放平台:https://open.alipay.com/ ...

  9. 微信支付Native扫码支付模式二之CodeIgniter集成篇

    CI:3.0.5 微信支付API类库来自:https://github.com/zhangv/wechat-pay 请先看一眼官方场景及支付时序图:https://pay.weixin.qq.com/ ...

随机推荐

  1. strrchr 一个获取扩展名的方便的php函数

    上传文件时,$_FILES里面的name是稳健的名称,要获取扩展名就用 strrchr(str,符号)来截取最后一个.后面的扩展名 然后用 trim 去掉特殊字符. 就可以得到扩展名了

  2. Cocos2d-x建工程时避免copy文件夹和库

    方法一:(官方做法) 打开F:\cocos2d-1.0.1-x-0.9.1目录下的cocos2d-win32.vc2010.sln文件,然后右键点击解决方案,选择"添加"—&quo ...

  3. Task 使用 Task以及Task&period;Factory都是在&period;Net 4引用的。Task跟Thread很类似,通过下面例子可以看到。

    static public void ThreadMain() { Thread t1 = new Thread(TaskWorker); t1.Start(3); } static public v ...

  4. &lowbar;&lowbar;device&lowbar;&lowbar; &lowbar;&lowbar;global&lowbar;&lowbar; &lowbar;&lowbar;host&lowbar;&lowbar;

    __device__ 标记的函数从一个在器件中执行的函数呼叫,在器件中执行 __global__ 表示该函数从一个在主机中执行的函数呼叫,在器件中执行 __host__表示在主机中呼叫,在主机中执行的 ...

  5. jquery expand

    /** * jquery-expand-1.0.js * author:tww **/ (function(){ /** * jQuery fadeTo expand. **/ jQuery.fn._ ...

  6. mini-tabs多个div并列&comma;并可隐藏某个div

    <div class="mini-tabs" activeIndex="0" id="tabs"> <div title= ...

  7. MySQL自定义函数与存储过程

    1.前置条件 MySQL数据库中存在表user_info,其结构和数据如下: mysql> desc user_info; +-----------+----------+------+---- ...

  8. Light Oj 1003

    题意 : 给你m个二元关系, 问是否可以确定各个节点的先后关系: 思路: 拓扑排序, 判断是否有环: #include<bits/stdc++.h> using namespace std ...

  9. 【原】Win7 host 与 virtualbox ubuntu guest 相同ping通

    环境:Win7 host 与 virtualbox ubuntu guest 在 “设置”-->"网络" 中选择网卡1,修改连接方式为 “桥接网卡” 后, 主机和虚拟机可以相 ...

  10. TF-IDF理解及其Java实现

    TF-IDF 前言 前段时间,又具体看了自己以前整理的TF-IDF,这里把它发布在博客上,知识就是需要不断的重复的,否则就感觉生疏了. TF-IDF理解 TF-IDF(term frequency–i ...