支付宝手机网页支付和微信公众号支付接入

  先说支付宝的吧。

       第一步:去支付宝新建沙箱应用并申请开通相应权限,也就是测试环境,完成后去https://auth.alipay.com/login/ant_sso_index.htm?goto=https%3A%2F%2Fopenhome.alipay.com%2Fplatform%2FappDaily.htm%3Ftab%3Dinfo查看自己的应用,在这里面会有APPID,支付宝网关等参数,密钥和支付宝公钥按提示生成即可,这些参数在之后代码中都会用到。

       第二步:自己服务器的代码部分,在写代码之前,先导入马爸爸为我们准备的SDK,Maven依赖如下,

<dependency>
  <groupId>com.alipay.sdk</groupId>
  <artifactId>alipay-sdk-java</artifactId>
  <version>3.4.27.ALL</version>
</dependency>复制代码

然后我们得先知道整个支付流程是怎么样的。按照一般逻辑,前端拿着订单ID请求后台的统一下单接口,此接口整理数据返回信息给前端,前端拿此信息请求支付宝开始支付,支付完成后根据return_url跳转前端页面同步通知,根据notify_url调用服务器后台接口异步通知

        下面进入正题:

        统一下单接口:从这里开始才是支付流程的第一步,整理数据给前端用以发起支付请求,这个接口里面需要的参数可以参考官方文档https://docs.open.alipay.com/api(这个是所有API的文档,找自己需要的接口看)。这里重点提一下,return_url和notify_url,return_url:同步跳转路径,是支付完成后前端跳转页面的路径,通常为某个html页面的路径,这个跳转只表示支付完成,意思是整个支付流程完成,并不代表支付成功或者失败。而notify_url为异步通知,一般为后端controller的requestMapping,这个才是真正通知支付成功或者失败的接口,后端要写一个接受支付宝返回信息的接口,下面再讲。这个统一下单接口会根据不同的请求方式会返回不同的信息,GET请求返回的是json或xml,POST则是直接返回一个带订单信息的form表单。前端拿到统一下单接口返回的信息后请求支付即可。

 public void alipay(UserEntity userEntity, HttpServletResponse response, Long id) {

  try {
    //根据订单ID从数据库获取订单信息用于请求支付宝接口的数据封装(这里最好是把当前登录的用户一起传入sql查询,防止查出非本人的订单)
    BookingOrderEntity bookingOrderEntity = userDao.getOrderDetail(userEntity.getId(), id);
    //封装公共参数    
    AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getGatewayUrl(), alipayConfig.getAppId(),
        alipayConfig.getMerchantPrivateKey(), "json", AlipayConfig.charset, alipayConfig.getAlipayPublicKey(),
        AlipayConfig.signType);
    //创建API对应的request(手机网页支付,APP支付均不同,此处根据自己需求更改)
    AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
    //在公共参数中设置前端同步回跳页面和后台异步通知路径
    alipayRequest.setReturnUrl(alipayConfig.getReturnUrl().replace("ID", bookingOrderEntity.getId().toString()));
    alipayRequest.setNotifyUrl(alipayConfig.getNotifyUrl());
    //填充业务参数,即订单信息
    String subject = bookingOrderEntity.getSnapshotHotelName() + "-" + bookingOrderEntity.getBookingNo();
    alipayRequest.setBizContent("{" +
        " \"out_trade_no\":" + bookingOrderEntity.getBookingNo() + "," + " \"total_amount\":" + bookingOrderEntity.getPayPrice() + "," + " \"subject\":\"" + subject + "\"," + " \"product_code\":\"QUICK_WAP_WAY\"" + " }"); //调用SDK生成表单 String form = alipayClient.pageExecute(alipayRequest).getBody(); response.setContentType("text/html;charset=utf-8"); //直接将完整的表单html输出到页面 response.getWriter().write(form); } catch (AlipayApiException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }复制代码

       支付宝参数实体类:我是写成了去配置文件拿信息的,各位也可以直接写成普通类放参数就行。

@Component
@ConfigurationProperties(prefix = "alipay")
public class AlipayConfig {

  /**
   * 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
   */
  @Value("${alipay.appId}")
  private String appId;

  /**
   * 商户私钥,您的PKCS8格式RSA2私钥
   */
  @Value("${alipay.merchantPrivateKey}") private String merchantPrivateKey; /** * 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。 */ @Value("${alipay.alipayPublicKey}") private String alipayPublicKey; /** * 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 */ @Value("${alipay.notifyUrl}") private String notifyUrl; /** * 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 */ @Value("${alipay.return_url}") private String returnUrl; /** * 支付宝网关 */ @Value("${alipay.gatewayUrl}") private String gatewayUrl; /** * 签名方式 */ public static String signType = "RSA2"; /** * 字符编码格式 */ public static String charset = "utf-8"; public String getAppId() { return appId; } public String getMerchantPrivateKey() { return merchantPrivateKey; } public String getAlipayPublicKey() { return alipayPublicKey; } public String getNotifyUrl() { return notifyUrl; } public String getReturnUrl() { return returnUrl; } public String getGatewayUrl() { return gatewayUrl; } public void setAppId(String appId) { this.appId = appId; } public void setMerchantPrivateKey(String merchantPrivateKey) { this.merchantPrivateKey = merchantPrivateKey; } public void setAlipayPublicKey(String alipayPublicKey) { this.alipayPublicKey = alipayPublicKey; } public void setNotifyUrl(String notifyUrl) { this.notifyUrl = notifyUrl; } public void setReturnUrl(String returnUrl) { this.returnUrl = returnUrl; } public void setGatewayUrl(String gatewayUrl) { this.gatewayUrl = gatewayUrl; } }复制代码

       POST返回的信息:是一个自动提交的form表单,前端直接加载即可。

 

       钉钉内网穿透:return_url和notify_url都必须是外网能够访问到的,如果在本地想要测试,可以下载一个钉钉内网穿透工具https://open-doc.dingtalk.com/microapp/debug/ucof2g,这里面以Mac为例讲了怎么使用,windows操作:cd至git克隆下来的目录,有mac和windows两个版本,进入windows的,不需要chmode命令,这个命令是用来改权限的,启动命令改为ding -config=ding.cfg -subdomain=a 8080即可。

        打开穿透工具:如下图,a为域名前缀,可自定义,8081为你自己本地后台服务器的端口。

      开启成功:如下图,这里好像只能使用http不能用https的,开启成功后只需将notify_url改为: http://a.vaiwan.com:8081/xxx/xxx即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值