前段时间开发了一个商城,集成了支付宝,微信,网银支付(接入的是连连支付第三方支付接口)。现在总结一下。
首先到https://www.alipay.com/ 注册一个支付宝商户号,进入开放平台,创建一个应用,签约电脑网站支付
接着配置应用信息:

这里的授权回调地址填的是支付宝付款成功后异步回调的地址,应用网关我填的是同步回调地址。下面的应用公钥需要自己设置
代码里面的配置:

package com.rongding.config;import java.io.FileWriter;
import java.io.IOException;/* **类名:AlipayConfig*功能:基础配置类*详细:设置帐户有关信息及返回路径*修改日期:2017-04-05*说明:*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。*该代码仅供学习和研究支付宝接口使用,只是提供一个参考。*/public class AlipayConfig {//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号public static String app_id = "";// 商户私钥,您的PKCS8格式RSA2私钥public static String merchant_private_key = "";// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。public static String alipay_public_key = "";// 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问public static String notify_url = "";// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问public static String return_url = "";// 签名方式public static String sign_type = "RSA2";// 字符编码格式public static String charset = "utf-8";// 支付宝网关  ,沙箱测试时使用  alipaydev  生产环境使用alipaypublic static String gatewayUrl = "https://openapi.alipay.com/gateway.do";// 支付宝网关public static String log_path = "C:\\";//可以不填// 商户uidpublic static String seller_id = "";
//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑/** * 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)* @param sWord 要写入日志里的文本内容*/public static void logResult(String sWord) {FileWriter writer = null;try {writer = new FileWriter(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();}}}}
}@Controller
public class OrderController {@Autowiredprivate HttpServletRequest request;@Autowiredprivate ReqProductService reqproductService;@Autowiredprivate TransreqService transreqService;@Autowired private AddressService addressService;@Autowiredprivate OrderService orderService;private Logger log = Logger.getLogger(OrderController.class);private String sendToAlipay(HttpServletRequest request,Map<String,Object> map) throws AlipayApiException{Transreq transreq = (Transreq) map.get("transreq");ReqProduct reqproduct = (ReqProduct) map.get("reqproduct");//获得初始化的AlipayClientAlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);//设置请求参数AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();alipayRequest.setReturnUrl(AlipayConfig.return_url);alipayRequest.setNotifyUrl(AlipayConfig.notify_url);//商户订单号,商户网站订单系统中唯一订单号,必填String out_trade_no = new String(transreq.getSerialNo());//付款金额,必填String total_amount = new String(DataUtil.formatDouble(transreq.getAmt().doubleValue(), 2));//订单名称,必填String subject = new String(reqproduct.getPrdName());//商品描述,可空String body = new String(reqproduct.getPrdName());alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\"," + "\"total_amount\":\""+ total_amount +"\"," + "\"subject\":\""+ subject +"\"," + "\"body\":\""+ body +"\"," + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");//若想给BizContent增加其他可选请求参数,以增加自定义超时时间参数timeout_express来举例说明//alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\"," //      + "\"total_amount\":\""+ total_amount +"\"," //      + "\"subject\":\""+ subject +"\"," //      + "\"body\":\""+ body +"\"," //      + "\"timeout_express\":\"10m\"," //      + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");//请求参数可查阅【电脑网站支付的API文档-alipay.trade.page.pay-请求参数】章节//请求String result = alipayClient.pageExecute(alipayRequest).getBody();return result;}@RequestMapping("aliPayNotify_url")@ResponseBodypublic String alipaynotify(Model model,HttpServletRequest request,HttpServletResponse response){log.info("支付宝异步回调 ------------beg-----------");/* ** 功能:支付宝服务器异步通知页面* 日期:2017-03-30* 说明:* 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。* 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。*************************页面功能说明************************** 创建该页面文件时,请留心该页面文件中无任何HTML代码及空格。* 该页面不能在本机电脑测试,请到服务器上做测试。请确保外部可以访问该页面。* 如果没有收到该页面返回的 success * 建议该页面只做支付成功的业务逻辑处理,退款的处理请以调用退款查询接口的结果为准。*/String result = "fail";//获取支付宝POST过来反馈信息Map<String,String> params = new HashMap<String,String>();Map<String,String[]> requestParams = request.getParameterMap();for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {String name = (String) iter.next();String[] values = (String[]) requestParams.get(name);String valueStr = "";for (int i = 0; i < values.length; i++) {valueStr = (i == values.length - 1) ? valueStr + values[i]: valueStr + values[i] + ",";}//乱码解决,这段代码在出现乱码时使用
//              try {//                  valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
//              } catch (UnsupportedEncodingException e) {//                  // TODO Auto-generated catch block
//                  e.printStackTrace();
//              }params.put(name, valueStr);}String contentS = AlipayFunction.CreateLinkString(params);log.debug("支付宝异步回调请求参数:"+contentS);boolean signVerified =false;try {signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);} catch (AlipayApiException e1) {// TODO Auto-generated catch blocklog.error("由于"+e1.getErrMsg()+"返回给支付宝系统的结果result:fail");model.addAttribute("result", "fail");return result;} //调用SDK验证签名//——请在这里编写您的程序(以下代码仅作参考)——/* 实际验证过程建议商户务必添加以下校验:1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)4、验证app_id是否为该商户本身。*/if(signVerified) {//验证成功//商户订单号//交易状态log.info("支付宝异步回调验签成功!");String trade_status = request.getParameter("trade_status");if("TRADE_FINISHED".equals(trade_status)){//判断该笔订单是否在商户网站中已经做过处理//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序//如果有做过处理,不执行商户的业务程序//注意://退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知try {dologic(request);result = "success";} catch (Exception e) {log.error(e.getMessage());result = "fail";}}else if ("TRADE_SUCCESS".equals(trade_status)){//判断该笔订单是否在商户网站中已经做过处理//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序//如果有做过处理,不执行商户的业务程序//注意://付款完成后,支付宝系统发送该交易状态通知try {dologic(request);result = "success";} catch (Exception e) {// TODO Auto-generated catch blocklog.error(e.getMessage());result = "fail";}}else{result = "fail";}//              out.println("success");}else {//验证失败
//              out.println("fail");result = "fail";//调试用,写文本函数记录程序运行情况是否正常//String sWord = AlipaySignature.getSignCheckContentV1(params);//AlipayConfig.logResult(sWord);log.debug("支付宝异步回调验签失败");}log.debug("异步回调返回给支付宝系统的结果result:"+result);model.addAttribute("result", result);log.info("支付宝异步回调  -------------end ------------");return result;}private void dologic(HttpServletRequest request) throws Exception{log.info("付款成功后处理商户业务逻辑 --------------beg--------------");//商户系统订单号String out_trade_no = request.getParameter("out_trade_no");//支付宝交易号String trade_no = request.getParameter("trade_no");//金额String total_amount = request.getParameter("total_amount");//app_idString app_id = request.getParameter("app_id");Transreq transreq =  transreqService.selectByPrimaryKey(out_trade_no);//购买流水if(transreq == null){throw new Exception("未查询到购买流水信息,商户逻辑处理失败,订单号为:"+out_trade_no);}if(!IDict.REQ_STATUS.REQ_STATUS_DFK.equals(transreq.getStatus())){//判断状态throw new Exception("该购买流水信息状态不为待付款,商户逻辑处理失败,订单号为:"+out_trade_no);}if(transreq.getAmt().subtract(new BigDecimal(total_amount)).compareTo(new BigDecimal("0.1"))>0){//判断金额throw new Exception("支付宝支付支付的金额与订单中的金额不一致,商户逻辑处理失败,订单号为:"+out_trade_no);};if(!AlipayConfig.app_id.equals(app_id)){//判断appid是否相同throw new Exception("支付宝支付异步反回的appid与商户appid不一致,商户逻辑处理失败,相应的订单号为:"+out_trade_no);}Transreq uploadtransreq = transreqService.selectByPrimaryKey(transreq.getAssoSerial());if(uploadtransreq == null){throw new Exception("支付宝支付异步回调时未找到与订单信息相关的上传商品的信息,商户逻辑处理失败,订单号为:"+out_trade_no);}if(!IDict.REQ_STATUS.REQ_STATUS_SUCCESS.equals(uploadtransreq.getStatus())){throw new Exception("支付宝支付异步回调时找到的与订单信息相关的上传商品的信息状态不正确,商户逻辑处理失败,订单号为:"+out_trade_no);}try {orderService.pay(transreq, uploadtransreq,trade_no);} catch (Exception e) {throw new RuntimeException("数据更新失败,订单号为:"+out_trade_no);}log.info("付款成功后处理商户业务逻辑 --------------end--------------");return ;}@RequestMapping("aliPayReturn_url")public String returnUrl(Model model,HttpServletRequest request,HttpServletResponse response){log.info("支付宝同步回调 ------------------beg--------------------");/* ** 功能:支付宝服务器同步通知页面* 日期:2017-03-30* 说明:* 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。* 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。*************************页面功能说明************************** 该页面仅做页面展示,业务逻辑处理请勿在该页面执行*/String result = null;//获取支付宝GET过来反馈信息Map<String,String> params = new HashMap<String,String>();Map<String,String[]> requestParams = request.getParameterMap();for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {String name = (String) iter.next();String[] values = (String[]) requestParams.get(name);String valueStr = "";for (int i = 0; i < values.length; i++) {valueStr = (i == values.length - 1) ? valueStr + values[i]: valueStr + values[i] + ",";}
//              //乱码解决,这段代码在出现乱码时使用
//              try {//                  valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
//              } catch (UnsupportedEncodingException e) {//                  // TODO Auto-generated catch block
//                  e.printStackTrace();
//              }params.put(name, valueStr);
//              System.out.println(name+":"+valueStr);}String contentS = AlipayFunction.CreateLinkString(params);log.debug("支付宝同步回调请求参数:"+contentS);boolean signVerified = false;try {signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);} catch (AlipayApiException e) {// TODO Auto-generated catch blocke.printStackTrace();} //调用SDK验证签名//——请在这里编写您的程序(以下代码仅作参考)——if(signVerified) {//商户订单号String  out_trade_no = request.getParameter("out_trade_no");//支付宝交易号String trade_no =  request.getParameter("trade_no");//付款金额String total_amount = request.getParameter("total_amount");result = "trade_no:"+trade_no+"<br/>out_trade_no:"+out_trade_no+"<br/>total_amount:"+total_amount;
//              out.println("trade_no:"+trade_no+"<br/>out_trade_no:"+out_trade_no+"<br/>total_amount:"+total_amount);log.debug("支付宝同步回调验签成功");}else {
//              out.println("验签失败");result = "验签失败";log.debug("支付宝同步回调验签失败");}model.addAttribute("result", result);log.info("支付宝同步回调 ------------------end--------------------");return "return_url";}
}

大致就是这样,支付宝的api给的还是比较好理解的,但是支付宝支付需要审核,审核的时候需要网站在外网上能够访问到。

pc端支付宝扫码支付相关推荐

  1. 微信支付 postman_(easywechat + Laravel 5.8)整理 PC 端微信扫码支付全过程

    php中文网最新课程 每日17点准时技术干货分享 业务场景描述: 用户点击站点页面的 "购买" --> 即弹出二维码 --> 用户用微信扫描二维码 --> 根据微 ...

  2. 微信扫码支付html,pc端微信扫码支付和支付宝在线支付

    本DEMO演示了PHP支付宝和微信扫码在线支付,支付成功后,在回调地址显示支付相关信息. 难易:中级 下载资源 下载积分: 888 积分 操作步骤: 1.修改配置文件 Application/comm ...

  3. PC端微信扫码支付二维码生成接口的调整

    目前原有的example下面的在线二维码生成接口被微信取消了,从而需要各个电商系统自己生成. 可参考开发文章demo中的phpqrcode.php程序进行生成并保存到电商系统本身的服务器上,然后取出进 ...

  4. 支付宝扫码支付-PC版(沙箱环境)

    前言 最近开发了PC端支付宝扫码支付的功能,使用的是沙箱环境.所谓的沙箱环境,其实就是支付宝提供的测试环境(毕竟正式环境需要营业执照等信息进行注册,注册通过后还有一些流程,才能进行正式的扫码支付.对于 ...

  5. Java PC端微信、支付宝扫码支付(二)

    Java PC端微信.支付宝扫码支付(二) 前几天写了微信支付,附上链接 https://blog.csdn.net/qq_43494610/article/details/90411391 ,今天抽 ...

  6. PC网站微信扫码支付,Native支付,“当前商户号暂不支持关联该类型的appid“,“签名错误,请检查后再试““springBoot 微信支付“

    springBoot 微信支付 PC网站微信扫码支付-Native支付 一.采坑大合集 1.当前商户号暂不支持关联该类型的appid 2.签名错误,请检查后再试 二.springboot集成微信支付D ...

  7. java调用支付宝扫码支付接口

    说明: 由于没有商户账号,所以本文使用的是沙箱账号,本质跟真实账号是一样的,是支付宝为了方便开发人员开发调试而推出的策略.在真实开发中将商户公钥等修改为真实的商户即可. 支付基本流程 用户下单 商户账 ...

  8. 支付宝扫码支付,回调和退款(沙箱环境配置和完整代码)

    支付宝扫码支付 最近重构项目时,负责了支付模块,微信扫码支付(NATIVE)和 支付宝扫码支付,也是第一次接触,虽然根据官方文档和一些博客写出来了,但是遇到的问题却很多,走了很多弯路,浪费了很多精力和 ...

  9. 视频教程-PHP支付宝扫码支付-PHP

    PHP支付宝扫码支付 我是一名计算机教师,从事于教学10多年,在计算机教学方面有丰富的经验. 孙培超 ¥40.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 APP订阅 ...

  10. PC 端微信扫码注册和登录

    一.前言 先声明一下,本文所注重点为实现思路,代码及数据库设计主要为了展现思路,如果对代码效率有着苛刻要求的项目切勿照搬. 相信做过微信开发的人授权这块都没少做过,但是一般来说我们更多的是为移动端的网 ...

最新文章

  1. NestIn VS插件 visual studio 中将同类CS文件放在一起显示
  2. 从四个层面落地,成为受欢迎、可信赖、懂技术的产品经理
  3. python求阶乘和
  4. 魔兽怀旧网站模块下载_一个人的网站重新设计和怀旧
  5. asp.net core WebAPI实现CRUD
  6. 前端学习(795):基本包装类型
  7. 软件设计师学习3——操作系统知识
  8. python有趣的代码-python有趣的一行代码
  9. 手机端和wap端页面的自适应技术方案
  10. 《系统集成项目管理》第十六章 变更管理
  11. 防爆和本安的概念理解
  12. 语音社交聊天app受欢迎的特点有哪些?
  13. 2022年CPU天梯图(7月更新)
  14. 带头节点 (非头指针) 双向循环链表 (doubly linked list)
  15. 英特尔推出SD卡巨细电脑 配Atom处理器
  16. 我的世界服务器修改id指令,我的世界指令怎么用,我的世界附魔指令id
  17. 教你怎么一下哄好赌气的女朋友​
  18. 你只需要做你一个让世界随之起舞的枭雄
  19. 自定义android模拟器,在模拟器上运行自定义Android ROM
  20. 洛谷 P1606 [USACO07FEB]荷叶塘Lilypad Pond(spfa+最短路计数) 题解

热门文章

  1. Promise then的嵌套
  2. win10 ipv4无网络连接
  3. UE4基础:自定义单例类(Singleton Class)
  4. ffi一些常见的错误
  5. 从这条博客开始转变!
  6. C语言 FlappyBird×马里奥
  7. 720度全景图有什么优势?
  8. 房东违反房屋租赁合同会怎么进行赔偿
  9. 黎曼 zeta 函数与黎曼猜想
  10. 微分方程之一阶线性及可降阶方程