支付宝支付
1、申请签约
目的是得到开拓利用的互助伙伴身份(PID)和MD5秘钥,申请地址(即时到账收款):https://b.alipay.com/order/productDetail.htm?productId=2015110218012942
申请办法在开放平台的文档上有详细解释,这里就不再赘述。
2、接入支付接口
在得到PID和秘钥后就可以接入接口了,首先在开放平台中下载官方的demo(java+MD5版本),支付宝的demo做的非常好,下载下来直接配置下jdk就可以运行了。如果碰着Java compiler level does not match缺点,解释你用的eclipse或myeclipse的jdk编译版本与demo的JDK编译版本不一致,修正下jdk编译版本就可以了。实在就用到了4个类,如下图
可以选择把支付功能单独做一个项目,在其他项目调用接口就可以支付,也可以整合到自己的项目里,为了好掩护我整合到自己的项目里了。把这四个类放到自己的项目中,引入相应的jar包
2.1、demo中类的解释
AlipayConfig.java类紧张是配置参数信息的类
package com.fahai.pay.alipay;
import com.fahai.utils.ProInfoUtil;
/
类名:AlipayConfig
功能:根本配置类
详细:设置帐户有关信息及返回路径
版本:3.4
修正日期:2016-03-08
解释:
以下代码只是为了方便商户测试而供应的样例代码,商户可以根据自己网站的须要,按照技能文档编写,并非一定要利用该代码。
该代码仅供学习和研究支付宝接口利用,只是供应一个参考。
/
public class AlipayConfig {
//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// 互助身份者ID,签约账号,以2088开头由16位纯数字组成的字符串,查看地址:https://b.alipay.com/order/pidAndKey.htm
public static String partner = \公众你自己的PID\公众;
// 收款支付宝账号,以2088开头由16位纯数字组成的字符串,一样平常情形下收款账号便是签约账号
public static String seller_id = partner;
// MD5密钥,安全考验码,由数字和字母组成的32位字符串,查看地址:https://b.alipay.com/order/pidAndKey.htm
public static String key = \"大众你自己的MD5秘钥\"大众;
// 做事器异步关照页面路径 需http://格式的完全路径,不能加?id=123这类自定义参数,必须外网可以正常访问
//异步关照页面,便是接管支付宝支付结果返复书息的Controller,可以处理自己的支付后的逻辑
//测试环境
public static String notify_url = ProInfoUtil.getInstance().getProperty(\"大众project_url\公众)+\"大众order/pay/aliPayOrder\"大众;
// 页面跳转同步关照页面路径 需http://格式的完全路径,不能加?id=123这类自定义参数,必须外网可以正常访问
//同步跳转的页面,便是支付宝支付成功后页面跳转的url
public static String return_url = ProInfoUtil.getInstance().getProperty(\"大众project_url\公众)+\"大众order/pay/payResponse\"大众;
// 署名办法
public static String sign_type = \"大众MD5\"大众;
// 调试用,创建TXT日志文件夹路径,见AlipayCore.java类中的logResult(String sWord)打印方法。
public static String log_path = \公众C:\\\公众;
// 字符编码格式 目前支持 gbk 或 utf-8
public static String input_charset = \公众utf-8\公众;
// 支付类型 ,无需修正
public static String payment_type = \公众1\公众;
// 调用的接口名,无需修正
public static String service = \"大众create_direct_pay_by_user\"大众;
//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//↓↓↓↓↓↓↓↓↓↓ 请在这里配置防钓鱼信息,如果没开通防钓鱼功能,为空即可 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// 防钓鱼韶光戳 若要利用请调用类文件submit中的query_timestamp函数
public static String anti_phishing_key = \公众\"大众;
// 客户真个IP地址 非局域网的外网IP地址,如:221.0.0.1
public static String exter_invoke_ip = \公众\"大众;
//↑↑↑↑↑↑↑↑↑↑请在这里配置防钓鱼信息,如果没开通防钓鱼功能,为空即可 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061AlipayCore.java是整理参数的工具类
package com.alipay.util;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.httpclient.methods.multipart.FilePartSource;
import org.apache.commons.httpclient.methods.multipart.PartSource;
import com.alipay.config.AlipayConfig;
/
类名:AlipayFunction
功能:支付宝接口公用函数类
详细:该类是要求、关照返回两个文件所调用的公用函数核心处理文件,不须要修正
版本:3.3
日期:2012-08-14
解释:
以下代码只是为了方便商户测试而供应的样例代码,商户可以根据自己网站的须要,按照技能文档编写,并非一定要利用该代码。
该代码仅供学习和研究支付宝接口利用,只是供应一个参考。
/
public class AlipayCore {
/
撤除数组中的空值和署名参数
@param sArray 署名参数组
@return 去掉空值与署名参数后的新署名参数组
/
public static Map<String, String> paraFilter(Map<String, String> sArray) {
Map<String, String> result = new HashMap<String, String>();
if (sArray == null || sArray.size() <= 0) {
return result;
}
for (String key : sArray.keySet()) {
String value = sArray.get(key);
if (value == null || value.equals(\"大众\公众) || key.equalsIgnoreCase(\公众sign\公众)
|| key.equalsIgnoreCase(\公众sign_type\公众)) {
continue;
}
result.put(key, value);
}
return result;
}
/
把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串
@param params 须要排序并参与字符拼接的参数组
@return 拼接后字符串
/
public static String createLinkString(Map<String, String> params) {
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
String prestr = \公众\"大众;
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
if (i == keys.size() - 1) {//拼接时,不包括末了一个&字符
prestr = prestr + key + \"大众=\"大众 + value;
} else {
prestr = prestr + key + \"大众=\"大众 + value + \"大众&\"大众;
}
}
return prestr;
}
/
写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
@param sWord 要写入日志里的文本内容
/
public static void logResult(String sWord) {
FileWriter writer = null;
try {
writer = new FileWriter(AlipayConfig.log_path + \"大众alipay_log_\"大众 + System.currentTimeMillis()+\"大众.txt\公众);
writer.write(sWord);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/
天生文件择要
@param strFilePath 文件路径
@param file_digest_type 择要算法
@return 文件择要结果
/
public static String getAbstract(String strFilePath, String file_digest_type) throws IOException {
PartSource file = new FilePartSource(new File(strFilePath));
if(file_digest_type.equals(\公众MD5\"大众)){
return DigestUtils.md5Hex(file.createInputStream());
}
else if(file_digest_type.equals(\公众SHA\公众)) {
return DigestUtils.sha256Hex(file.createInputStream());
}
else {
return \"大众\"大众;
}
}
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122AlipayNotify.java是验证署名的类
package com.alipay.util;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import com.alipay.config.AlipayConfig;
import com.alipay.sign.MD5;
/
类名:AlipayNotify
功能:支付宝关照处理类
详细:处理支付宝各接口关照返回
版本:3.3
日期:2012-08-17
解释:
以下代码只是为了方便商户测试而供应的样例代码,商户可以根据自己网站的须要,按照技能文档编写,并非一定要利用该代码。
该代码仅供学习和研究支付宝接口利用,只是供应一个参考
把稳
调试关照返回时,可查看或改写log日志的写入TXT里的数据,来检讨关照返回是否正常
/
public class AlipayNotify {
/
支付宝验证地址
/
private static final String HTTPS_VERIFY_URL = \公众https://mapi.alipay.com/gateway.do?service=notify_verify&\公众;
/
验证是否是支付宝发出的合法
@param params 关照返回来的参数数组
@return 验证结果
/
public static boolean verify(Map<String, String> params) {
//判断responsetTxt是否为true,isSign是否为true
//responsetTxt的结果不是true,与做事器设置问题、互助身份者ID、notify_id一分钟失落效有关
//isSign不是true,与安全校验码、要求时的参数格式(如:带自定义参数等)、编码格式有关
String responseTxt = \"大众false\"大众;
if(params.get(\"大众notify_id\公众) != null) {
String notify_id = params.get(\"大众notify_id\"大众);
responseTxt = verifyResponse(notify_id);
}
String sign = \"大众\"大众;
if(params.get(\公众sign\"大众) != null) {sign = params.get(\公众sign\"大众);}
boolean isSign = getSignVeryfy(params, sign);
//写日志记录(若要调试,请取消下面两行注释)
//String sWord = \"大众responseTxt=\"大众 + responseTxt + \公众\n isSign=\公众 + isSign + \"大众\n 返回回来的参数:\"大众 + AlipayCore.createLinkString(params);
//AlipayCore.logResult(sWord);
if (isSign && responseTxt.equals(\"大众true\"大众)) {
return true;
} else {
return false;
}
}
/
根据反馈回来的信息,天生署名结果
@param Params 关照返回来的参数数组
@param sign 比对的署名结果
@return 天生的署名结果
/
private static boolean getSignVeryfy(Map<String, String> Params, String sign) {
//过滤空值、sign与sign_type参数
Map<String, String> sParaNew = AlipayCore.paraFilter(Params);
//获取待署名字符串
String preSignStr = AlipayCore.createLinkString(sParaNew);
//得到署名验证结果
boolean isSign = false;
if(AlipayConfig.sign_type.equals(\"大众MD5\"大众) ) {
isSign = MD5.verify(preSignStr, sign, AlipayConfig.key, AlipayConfig.input_charset);
}
return isSign;
}
/
获取远程做事器ATN结果,验证返回URL
@param notify_id 关照校验ID
@return 做事器ATN结果
验证结果集:
invalid命令参数不对 涌现这个缺点,请检测返回处理中partner和key是否为空
true 返回精确信息
false 请检讨防火墙或者是做事器阻挡端口问题以及验证韶光是否超过一分钟
/
private static String verifyResponse(String notify_id) {
//获取远程做事器ATN结果,验证是否是支付宝做事器发来的要求
String partner = AlipayConfig.partner;
String veryfy_url = HTTPS_VERIFY_URL + \"大众partner=\公众 + partner + \公众¬ify_id=\"大众 + notify_id;
return checkUrl(veryfy_url);
}
/
获取远程做事器ATN结果
@param urlvalue 指定URL路径地址
@return 做事器ATN结果
验证结果集:
invalid命令参数不对 涌现这个缺点,请检测返回处理中partner和key是否为空
true 返回精确信息
false 请检讨防火墙或者是做事器阻挡端口问题以及验证韶光是否超过一分钟
/
private static String checkUrl(String urlvalue) {
String inputLine = \"大众\"大众;
try {
URL url = new URL(urlvalue);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection
.getInputStream()));
inputLine = in.readLine().toString();
} catch (Exception e) {
e.printStackTrace();
inputLine = \公众\公众;
}
return inputLine;
}
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124AlipaySubmit.java仿照form表单要求支付宝支付接口的类
package com.alipay.util;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import com.alipay.config.AlipayConfig;
import com.alipay.sign.MD5;
/
类名:AlipaySubmit
功能:支付宝各接口要求提交类
详细:布局支付宝各接口表单HTML文本,获取远程HTTP数据
版本:3.3
日期:2012-08-13
解释:
以下代码只是为了方便商户测试而供应的样例代码,商户可以根据自己网站的须要,按照技能文档编写,并非一定要利用该代码。
该代码仅供学习和研究支付宝接口利用,只是供应一个参考。
/
public class AlipaySubmit {
/
支付宝供应给商户的做事接入网关URL(新)
/
private static final String ALIPAY_GATEWAY_NEW = \"大众https://mapi.alipay.com/gateway.do?\"大众;
/
天生署名结果
@param sPara 要署名的数组
@return 署名结果字符串
/
public static String buildRequestMysign(Map<String, String> sPara) {
String prestr = AlipayCore.createLinkString(sPara); //把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
String mysign = \公众\公众;
if(AlipayConfig.sign_type.equals(\公众MD5\公众) ) {
mysign = MD5.sign(prestr, AlipayConfig.key, AlipayConfig.input_charset);
}
return mysign;
}
/
天生要要求给支付宝的参数数组
@param sParaTemp 要求前的参数数组
@return 要要求的参数数组
/
private static Map<String, String> buildRequestPara(Map<String, String> sParaTemp) {
//撤除数组中的空值和署名参数
Map<String, String> sPara = AlipayCore.paraFilter(sParaTemp);
//天生署名结果
String mysign = buildRequestMysign(sPara);
//署名结果与署名办法加入要求提交参数组中
sPara.put(\"大众sign\公众, mysign);
sPara.put(\"大众sign_type\"大众, AlipayConfig.sign_type);
return sPara;
}
/
建立要求,以表单HTML形式布局(默认)
@param sParaTemp 要求参数数组
@param strMethod 提交办法。两个值可选:post、get
@param strButtonName 确认按钮显示笔墨
@return 提交表单HTML文本
/
public static String buildRequest(Map<String, String> sParaTemp, String strMethod, String strButtonName) {
//待要求参数数组
Map<String, String> sPara = buildRequestPara(sParaTemp);
List<String> keys = new ArrayList<String>(sPara.keySet());
StringBuffer sbHtml = new StringBuffer();
sbHtml.append(\"大众<form id=\\公众alipaysubmit\\公众 name=\\公众alipaysubmit\\公众 action=\\"大众\"大众 + ALIPAY_GATEWAY_NEW
+ \"大众_input_charset=\公众 + AlipayConfig.input_charset + \公众\\"大众 method=\\"大众\"大众 + strMethod
+ \公众\\"大众>\"大众);
for (int i = 0; i < keys.size(); i++) {
String name = (String) keys.get(i);
String value = (String) sPara.get(name);
sbHtml.append(\"大众<input type=\\公众hidden\\公众 name=\\"大众\"大众 + name + \"大众\\"大众 value=\\"大众\"大众 + value + \"大众\\"大众/>\"大众);
}
//submit按钮控件请不要含有name属性
sbHtml.append(\"大众<input type=\\公众submit\\公众 value=\\公众\公众 + strButtonName + \"大众\\"大众 style=\\"大众display:none;\\"大众></form>\公众);
sbHtml.append(\"大众<script>document.forms['alipaysubmit'].submit();</script>\"大众);
return sbHtml.toString();
}
/
用于防钓鱼,调用接口query_timestamp来获取韶光戳的处理函数
把稳:远程解析XML出错,与做事器是否支持SSL等配置有关
@return 韶光戳字符串
@throws IOException
@throws DocumentException
@throws MalformedURLException
/
public static String query_timestamp() throws MalformedURLException,
DocumentException, IOException {
//布局访问query_timestamp接口的URL串
String strUrl = ALIPAY_GATEWAY_NEW + \公众service=query_timestamp&partner=\"大众 + AlipayConfig.partner + \"大众&_input_charset\"大众 +AlipayConfig.input_charset;
StringBuffer result = new StringBuffer();
SAXReader reader = new SAXReader();
Document doc = reader.read(new URL(strUrl).openStream());
List<Node> nodeList = doc.selectNodes(\"大众//alipay/\"大众);
for (Node node : nodeList) {
// 截取部分不须要解析的信息
if (node.getName().equals(\"大众is_success\公众) && node.getText().equals(\"大众T\"大众)) {
// 判断是否有成功标示
List<Node> nodeList1 = doc.selectNodes(\公众//response/timestamp/\"大众);
for (Node node1 : nodeList1) {
result.append(node1.getText());
}
}
}
return result.toString();
}
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135这几个类调用支付宝接口的是AlipaySubmit,在网页选好购买的商品时,在系统中天生订单,然后进行支付,浏览器跳转到支付宝支付网站,Controller中代码为:
/
支付宝支付页面
@return
@throws IOException
/
@RequestMapping(value = \"大众/aliPay\"大众)
public void aliPay(HttpServletRequest request, HttpServletResponse response) throws IOException {
LOGGER.info(\"大众支付宝支付页面\公众);
//商户订单号,商户网站订单系统中唯一订单号,必填
String orderNo = request.getParameter(\"大众orderNo\公众);
//订单名称,必填
String subjectName = request.getParameter(\"大众subjectName\"大众);
//付款金额,必填
String total_fee = request.getParameter(\"大众fee\"大众);
//商品描述,可空
String body = \公众法海风控 \"大众 + subjectName;
if (\公众money\"大众.equals(body)) {
body = \"大众法海风控 余额充值\公众;
}
//把要求参数打包成map
Map<String, String> sParaTemp = new HashMap<String, String>();
sParaTemp.put(\"大众service\公众, AlipayConfig.service);
sParaTemp.put(\"大众partner\"大众, AlipayConfig.partner);
sParaTemp.put(\"大众seller_id\"大众, AlipayConfig.seller_id);
sParaTemp.put(\"大众_input_charset\"大众, AlipayConfig.input_charset);
sParaTemp.put(\"大众payment_type\公众, AlipayConfig.payment_type);
sParaTemp.put(\公众notify_url\"大众, AlipayConfig.notify_url);
sParaTemp.put(\"大众return_url\"大众, AlipayConfig.return_url);
sParaTemp.put(\"大众anti_phishing_key\"大众, AlipayConfig.anti_phishing_key);
sParaTemp.put(\公众exter_invoke_ip\公众, AlipayConfig.exter_invoke_ip);
sParaTemp.put(\"大众out_trade_no\"大众, orderNo);
sParaTemp.put(\"大众subject\"大众, subjectName);
sParaTemp.put(\公众total_fee\公众, total_fee);
sParaTemp.put(\公众body\"大众, body);
//其他业务参数根据在线开拓文档,添加参数.文档地址:https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.O9yorI&treeId=62&articleId=103740&docType=1
//如sParaTemp.put(\"大众参数名\"大众,\公众参数值\公众);
//建立要求
String sHtmlText = AlipaySubmit.buildRequest(sParaTemp,\"大众get\公众,\公众确认\公众);
response.setHeader(\"大众Content-Type\公众, \"大众text/html; charset=UTF-8\"大众);
response.setCharacterEncoding(\"大众UTF-8\"大众);
PrintWriter out = response.getWriter();
System.out.println(sHtmlText);
out.println(sHtmlText);
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546要求aliPay会跳转到支付宝支付页面:
3、吸收支付结果关照
在配置好notify_url之后,支付结果会要求相应的接口,我的是order/pay/aliPayOrder,代码如下
/
支付宝支付订单
@return
@throws IOException
/
@ResponseBody
@RequestMapping(value = \公众pay/aliPayOrder\公众, method = RequestMethod.POST)
public void aliPayOrder(HttpServletRequest request,HttpServletResponse response) throws IOException {
LOGGER.info(\公众支付订单\"大众);
//从request中得到参数Map,并返回可读的Map
Map<String, String> params = RequestUtil.getParameterMap(request);
LOGGER.info(params.toString());
//验证支付宝署名
boolean aliSign = AlipayNotify.verify(params);
if (aliSign) {//验证成功
//交易状态
String tradeStatus = params.get(\"大众trade_status\"大众);
//订单编号
String orderNo = params.get(\"大众out_trade_no\"大众);
//支付单号
String payNo = params.get(\公众trade_no\"大众);
//支付账号
String payAccount = params.get(\公众buyer_email\"大众);
//支付金额
String totalFee = params.get(\公众total_fee\"大众);
//收款支付宝账号
String sellerId = params.get(\"大众seller_id\公众);
if (Constant.ALIPAY_TRADE_SUCCESS.equals(tradeStatus)) {//支付宝支付状态为成功
//验证支付宝返复书息与要求信息同等
if (ProInfoUtil.getInstance().getProperty(\"大众alipay_partner\"大众).equals(sellerId)) {
//订单处理状态
String orderHandleStatus = \"大众error\公众;
//验证订单未做支付处理
Order order = orderService.queryOrderByOrderNo(orderNo);
//订单已支付
if (Constant.DEALSTATUS_PAY.equals(order.getDealStatus())) {
response.getWriter().print(\公众success\"大众);
return;
}
if (null != order && Double.parseDouble(totalFee) == order.getDealPrice() &&
Constant.DEALSTATUS_NOT_PAY.equals(order.getDealStatus())) {//验证金额是否和订单同等
//更新订单为已支付、更新用户套餐余额、添加用户充值记录、添加用户余额支出记录
order.setDealStatus(Constant.DEALSTATUS_PAY);
order.setPayNo(payNo);
order.setPayType(Constant.ALIPAY);
order.setPayAccount(payAccount);
try {
//支付成功处理支付业务
boolean result = orderService.payOrder(order);
if (result) {
//成功后向支付宝返回成功标志
LOGGER.info(\公众支付宝支付成功\"大众);
orderHandleStatus = \"大众success\公众;
response.getWriter().print(\"大众success\公众);
}
} catch (Exception e) {
e.printStackTrace();
LOGGER.info(\公众支付宝支付失落败\公众);
response.getWriter().print(\"大众fail\"大众);
}
}
//添加支付信息
Map<String, Object> map = new HashMap<String, Object>();
map.put(\公众params\"大众, params.toString());
map.put(\"大众payType\"大众, Constant.ALIPAY);
map.put(\"大众orderNo\"大众, orderNo);
map.put(\公众handleStatus\"大众, orderHandleStatus);
orderService.addPayInfo(map);
}
}
} else {//验证失落败
LOGGER.info(\"大众支付宝返回验证失落败\"大众);
response.getWriter().print(\公众fail\"大众);
}
}
/
从request中得到参数Map,并返回可读的Map
@param request
@return
/
@SuppressWarnings(\"大众unchecked\"大众)
public static Map getParameterMap(HttpServletRequest request) {
// 参数Map
Map properties = request.getParameterMap();
// 返回值Map
Map<String, String> returnMap = new HashMap<String, String>();
Iterator entries = properties.entrySet().iterator();
Map.Entry entry;
String name = \"大众\"大众;
String value = \"大众\公众;
while (entries.hasNext()) {
entry = (Map.Entry) entries.next();
name = (String) entry.getKey();
Object valueObj = entry.getValue();
if(null == valueObj){
value = \公众\公众;
}else if(valueObj instanceof String[]){
String[] values = (String[])valueObj;
for(int i=0;i<values.length;i++){
value = values[i] + \"大众,\"大众;
}
value = value.substring(0, value.length()-1);
}else{
value = valueObj.toString();
}
returnMap.put(name, value);
}
return returnMap;
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115至此,支付宝支付功能已经做完了,个中有几个细节须要添加,比如支付时查询订单状态是否已经支付,是否过期等等,可以根据自己的需求去完善。
支付宝的接入还是很顺利的,如果闇练的话一两天就可以完成了,刚开始写博客,有缺点或者不明白的地方欢迎大家指出一起互换学习,共同进步。
由于篇幅问题,我不才一章先容微信支付的接入。