支付宝沙箱支付-详细版有案例

支付宝支付介绍

一、沙箱环境_介绍

(一)简介

沙箱环境 (Beta) 是支付宝开放平台为开发者提供的与线上环境完全隔离的联调测试环境,在沙箱环境中完成的调用不会对线上数据造成任何影响,尤其适合涉及资金链路的能力的调试。

注意:

  • 由于沙箱为模拟环境,在沙箱完成接口开发及主要功能调试后,请务必在正式环境进行完整的功能验收测试。所有返回码及业务逻辑以正式环境为准。
  • 为保证沙箱稳定,沙箱环境测试数据会进行定期数据清理。Beta 测试阶段每周日中午 12 点至每周一中午 12 点为维护时间,在此时间内沙箱环境部分功能可能不可用,敬请谅解。
  • 请勿在沙箱进行压力测试,以免触发相应的限流措施,导致无法正常使用沙箱环境。

**网址:**https://opendocs.alipay.com/common/02kkv7

(二)沙箱账号和沙箱应用

https://open.alipay.com/develop/sandbox/app

(三)支付宝客户端沙箱版

在这里插入图片描述

实时效果反馈

1.支付宝支付提供沙箱环境主要作用是*__**__*___。

A 娱乐使用

B 解决线上支付环境安全性

C 与线上环境完全隔离的测试环境

D 以上都是错误

2.支付宝客户端沙箱版,目前沙箱钱包仅提供*__**__*___版本。

A Android

B IOS

C APP

D 以上都是错误

答案

1=>C 2=>A

(四)沙箱秘钥

在沙箱进行调试前需要确保已经配置密钥/证书用于加签,支付宝提供了 系统默认密钥自定义密钥 两种方式进行配置。

设置沙箱应用的公钥和私钥

开发者如需使用系统默认密钥/证书,可在 开发信息 中选择 系统默认密钥

image-20220418214730137

安装支付宝开放平台助手

下载支付宝开放平台助手https://opendocs.alipay.com/common/02khjo

image-20220418215120968

生成密钥

在这里插入图片描述

详细步骤:

会自动生成商户应用公钥和应用私钥。

点击“打开密钥文件路径”,即可找到生成的公私钥。

在这里插入图片描述

注意:

生成的私钥需妥善保管,避免遗失,不要泄露。应用私钥需填写到代码中供签名时使用。应用公钥需提供给支付宝账号管理者上传到支付宝开放平台。

在这里插入图片描述

保存设置

在这里插入图片描述

二、沙箱支付

1、支付环境准备

1)沙箱环境准备

登录支付宝开放平台:https://open.alipay.com/

在支付宝开放平台左上角点击“控制台”,会出现如下界面:
在这里插入图片描述

在最下方有个沙箱,点进去,就进入沙箱环境了:

在这里插入图片描述

在支付宝沙箱环境中能找到APPID网关秘钥配置(这里选择自定义秘钥)

在这里插入图片描述

2)秘钥生成及配置

下载地址:https://opendocs.alipay.com/common/02kipk?pathHash=0d20b438
选择自己的操作系统下载即可,我这里是 Windows

在这里插入图片描述

下载完成后,生成密钥

在这里插入图片描述

生成应用公钥和应用私钥

应用公钥:用于在下方生成支付宝公钥。

在这里插入图片描述

配置接口加签方式

按步骤 查看 -> 复制刚刚生成的应用公钥到下图 -> 保存

在这里插入图片描述

然后我们就接入了支付宝开放平台

在这里插入图片描述

点击确定即可

2、内网穿透环境准备

NATAPP:https://natapp.cn/

1)创建隧道

先在注册一个新的账号

然后购买一个免费隧道

在这里插入图片描述

在 我的隧道 里面有刚刚购买的隧道

在这里插入图片描述

记住这里有个 authtoken,等下有用

2)修改隧道配置

在这里插入图片描述

修改端口为:8081

在这里插入图片描述

3)下载客户端

点击右上角客户端,下载对应的版本

在这里插入图片描述

下载完成之后为下图的 natapp.exe

在这里插入图片描述

运行 natapp.exe

**注意:**这里面不是点击运行。

通过在地址栏里面输入cmd命令,回车,打开命令提示窗口:

在这里插入图片描述

输入以下命令:

natapp.exe -authtoken=你的authtoken

在这里插入图片描述

启动成功如下图:

在这里插入图片描述

3、后端开发

1)引入阿里Maven坐标

<!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-easysdk -->
<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.9.28.ALL</version>
</dependency>

2)服务端代码配置

参数配置:

需要准备如下代码配置:

  • 支付宝网关地址:https://openapi-sandbox.dl.alipaydev.com/gateway.do
  • APPID:支付宝开发平台中的APPID
  • 签名方式:RSA2
  • 应用公钥、应用私钥:存在于 密钥工具中
创建沙箱支付配置文件 application.yaml
alipay:
  appId: 你的APPID
  merchantPrivateKey: 你的应用私钥
  alipayPublicKey: 你的应用公钥
  notifyUrl: http://内网穿透地址/api/alipay/notify
  returnUrl: http://member.zyz.com/memberOrder.html
  signType: RSA2
  charset: utf-8
  # 我的支付宝网关地址
  gatewayUrl: https://openapi-sandbox.dl.alipaydev.com/gateway.do
创建订单实体类:
package com.student.Pojo;

//import com.baomidou.mybatisplus.annotation.IdType;
//import com.baomidou.mybatisplus.annotation.TableField;
//import com.baomidou.mybatisplus.annotation.TableId;
//import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.ToString;

import java.io.Serializable;
import java.util.Date;

/**
 * 接口次数订单表
 * @TableName order
 */
@ToString
//@TableName(value ="`order`")
@Data
public class Order implements Serializable {
    /**
     * 订单Id
     */
//    @TableId(type = IdType.ASSIGN_UUID)
    private Long id;

    /**
     * 用户Id
     */
    private Long userId;

    /**
     * 接口Id
     */
    private Long interfaceInfoId;

    /**
     * 支付金额
     */
    private Double money;

    /**
     * 支付方式
     */
    private String paymentMethod;

    /**
     * 0 - 未支付 1 - 已支付
     */
    private Integer status;

    /**
     * 创建时间
     */
    private Date createTime;

    /**
     * 更新时间
     */
    private Date updateTime;

    /**
     * 是否删除
     */
    private Integer isDelete;

//    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}
支付模板

这里PC端网页支付模板,我准备了两个,1是输入账号密码支付,2是沙箱支付宝扫码支付。两种

账号密码支付模板

创建支付配置类,使用@Value注解将配置文件中的属性值映射到对应的属性中

package com.wei.project.manager;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.wei.weiapicommon.model.entity.Order;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;


@ConfigurationProperties(prefix = "alipay")
@Component
@Data
public class AlipayTemplate {
    // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
    @Value("{alipay.appId}")

    public String appId;

    // 应用私钥,就是工具生成的应用私钥
    @Value("{alipay.merchantPrivateKey}")
    public String merchantPrivateKey;
    // 支付宝公钥,对应APPID下的支付宝公钥。
    @Value("{alipay.alipayPublicKey}")
    public String alipayPublicKey;

    // 支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息
    @Value("{alipay.notifyUrl}")
    public String notifyUrl;
    //同步通知,支付成功,一般跳转到成功页
    @Value("{alipay.returnUrl}")
    public String returnUrl;

    // 签名方式
    @Value("{alipay.signType}")
    private String signType;

    // 字符编码格式
    @Value("{alipay.charset}")
    private String charset;

    //订单超时时间
    private String timeout = "1m";
    // 支付宝网关;https://openapi-sandbox.dl.alipaydev.com/gateway.do
    @Value("{alipay.gatewayUrl}")
    public String gatewayUrl;

    public String pay(Order order) throws
            AlipayApiException {

        //1、根据支付宝的配置生成一个支付客户端
         AlipayClient alipayClient = new
                DefaultAlipayClient(gatewayUrl, appId, merchantPrivateKey,
                "json", charset, alipayPublicKey, signType);

        //2、创建一个支付请求,并设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(returnUrl);
        alipayRequest.setNotifyUrl(notifyUrl);

        Long id = order.getId();
        Long interfaceInfoId = order.getInterfaceInfoId();
        Double money = order.getMoney();
        String paymentMethod = order.getPaymentMethod();


        alipayRequest.setBizContent(" {\"out_trade_no\":\"" + id + "\","
                + "\"total_amount\":\"" + money + "\","
                + "\"subject\":\"" + interfaceInfoId
                + "\","
                + "\"body\":\"" + paymentMethod + "\","
                +
                "\"timeout_express\":\"" + timeout + "\","
                +
                "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        //会收到支付宝的响应,响应的是一个页面,只要浏览器显示这个页面,就会自动来到支付宝的收银台页面
        System.out.println("支付宝的响应:" + result);
        return result;
    }
}

扫码支付模板
package com.student.config;

import cn.hutool.json.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;

import com.student.Pojo.Order;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;


//输入账号密码支付
@ConfigurationProperties(prefix = "alipay")
@Component
@Data
public class AlipayTemplate2 {
    // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
    @Value("{alipay.appId}")

    public String appId;

    // 应用私钥,就是工具生成的应用私钥
    @Value("{alipay.merchantPrivateKey}")
    public String merchantPrivateKey;
    // 支付宝公钥,对应APPID下的支付宝公钥。
    @Value("{alipay.alipayPublicKey}")
    public String alipayPublicKey;

    // 支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息
    @Value("{alipay.notifyUrl}")
    public String notifyUrl;
    //同步通知,支付成功,一般跳转到成功页
    @Value("{alipay.returnUrl}")
    public String returnUrl;

    // 签名方式
    @Value("{alipay.signType}")
    private String signType;

    // 字符编码格式
    @Value("{alipay.charset}")
    private String charset;

    //订单超时时间
    private String timeout = "1m";
    // 支付宝网关;https://openapi-sandbox.dl.alipaydev.com/gateway.do
    @Value("{alipay.gatewayUrl}")
    public String gatewayUrl;

    public String pay(Order order) throws
            AlipayApiException {

        //1、根据支付宝的配置生成一个支付客户端
        AlipayClient alipayClient = new
                DefaultAlipayClient(gatewayUrl, appId, merchantPrivateKey,
                "json", charset, alipayPublicKey, signType);

        //2、创建一个支付请求,并设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(returnUrl);
        alipayRequest.setNotifyUrl(notifyUrl);

        JSONObject bizContent = new JSONObject();
        bizContent.set("out_trade_no", order.getId());  // 我们自己生成的订单编号
        bizContent.set("total_amount", order.getMoney()); // 订单的总金额
        bizContent.set("subject", "XXX医院支付");   // 支付的名称
        bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY");  // 固定配置
        bizContent.set("body", "XXX医院收费单");
        bizContent.set("timeout_express", "30m");  // 订单的超时时间

        alipayRequest.setBizContent(bizContent.toString());

        String result = alipayClient.pageExecute(alipayRequest).getBody();
        //会收到支付宝的响应,响应的是一个页面,只要浏览器显示这个页面,就会自动来到支付宝的收银台页面
//        System.out.println("支付宝的响应:" + result);
        return result;
    }
}

控制层代码
package com.student.controller;

import cn.hutool.core.bean.BeanUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.student.Pojo.Order;
import com.student.config.AlipayTemplate;
import com.student.config.AlipayTemplate2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 支付宝接口
 */
@RestController
@RequestMapping("/alipay")
public class AliPayController {

    //扫码支付模板
//    @Resource
//    AlipayTemplate alipayTemplate;

    //账号密码支付模板
    @Autowired
    AlipayTemplate2 alipayTemplate;


    @GetMapping(value = "/pay", produces = "text/html;charset=utf-8")
    public String pay(@RequestParam("id") long id) throws AlipayApiException, IOException {
        Order order = new Order();
        order.setId(120948759374234L);//每次请求一定要不一致
        order.setUserId(129905052947L);
        order.setInterfaceInfoId(294389572235L);
        order.setMoney(65.0);
        order.setPaymentMethod("支付宝");
        return alipayTemplate.pay(order);
    }

    @PostMapping("/notify")  // 注意这里必须是POST接口
    public String payNotify(HttpServletRequest request) throws Exception {
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            System.out.println("=========支付宝异步回调========");

            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                params.put(name, request.getParameter(name));
                // System.out.println(name + " = " + request.getParameter(name));
            }

            String tradeNo = params.get("out_trade_no");
            String gmtPayment = params.get("gmt_payment");
            String alipayTradeNo = params.get("trade_no");
            // 支付宝验签

            boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayTemplate.alipayPublicKey, alipayTemplate.getCharset(), alipayTemplate.getSignType()); //调用SDK验证签名
            System.out.println(signVerified);
            if (signVerified) {
                // 验签通过
                System.out.println("交易名称: " + params.get("subject"));
                System.out.println("交易状态: " + params.get("trade_status"));
                System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
                System.out.println("商户订单号: " + params.get("out_trade_no"));
                System.out.println("交易金额: " + params.get("total_amount"));
                System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
                System.out.println("买家付款时间: " + params.get("gmt_payment"));
                System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
                // 更新订单状态
            }
        }
        return "success";
    }


}


启动类
package com.student.alipay;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan("com.student.*")
@SpringBootApplication
public class AliPayApplication {
    public static void main(String[] args) {
        SpringApplication.run(AliPayApplication.class, args);
    }
}

3)前端测试

前端通过传入订单 id 的方式去支付订单

在浏览器输入:http://localhost:8081/alipay/pay?id=167,如果页面成功跳转,则配置成功。

**注意:**如果出现订单参数错误,请将订单ID修改一下,务必保证每次请求订单号不一致。

页面跳转成功后会出现如下界面:

在这里插入图片描述

### 微信小程序集成支付宝沙箱环境配置教程 #### 一、准备工作 为了在微信小程序中集成并测试支付宝支付功能,开发者需先完成一些必要的准备事项。 - **注册入驻支付宝开放平台**:访问支付宝开放平台官网,按照指引完成企业或个人的注册流程[^1]。 - **获取API权限**:确保已申请获得相应的接口调用权限,特别是针对移动设备端的支付服务接口。这一步骤通常是在完成了身份验证之后自动授予或者是通过特定渠道单独申请得到许可。 - **创建应用与密钥管理**:进入开发者中心后新建一个用于实验的应用程序实例,并设置好公私钥对以便后续签名验签操作;同时记录下分配给该应用程序的一系列重要参数如`app_id`等信息以备将来使用。 #### 二、配置沙箱环境 接下来要做的就是搭建适合本地调试用途的安全隔离区域——即所谓的“沙盒”。 - **启用沙箱模式**:前往控制面板找到对应选项开启此功能开关,这样就可以在一个相对独立的空间里自由尝试各种可能遇到的情况而不用担心会影响到正式生产系统的稳定性了。 - **下载安装模拟器**:根据官方文档指示选择合适的安卓虚拟机本进行部署,这里推荐采用网易MuMu Player作为首选方案之一因为其良好的兼容性和易用性表现突出[^4]。记得把文件放置于英文路径之下以免造成不必要的麻烦! - **加载自定义APK包**:从指定链接处取得经过特别定制过的客户端软件副本(请注意保护个人信息安全),将其导入上述提到过的仿真工具之中完成初步设定工作。 #### 三、实现支付逻辑 当一切就绪之后便可以着手编写具体的业务代码来处理实际交易事务了。 对于基于Java语言构建的服务端而言,借助流行的微框架Spring Boot能够极大地简化整个开发周期内的各项任务执行难度: ```java // 导入所需依赖库 import com.alipay.api.AlipayApiException; import com.alipay.api.internal.util.AlipaySignature; @RestController @RequestMapping("/alipay") public class AlipayController { @PostMapping("/pay") public String pay(@RequestParam Map<String, String> params) throws AlipayApiException { // 设置公共请求参数 params.put("app_id", "your_app_id"); params.put("method", "alipay.trade.app.pay"); params.put("charset", "utf-8"); params.put("sign_type", "RSA2"); // 构造具体订单详情描述对象... StringBuilder orderInfo = new StringBuilder(); orderInfo.append("biz_content={\"out_trade_no\":\"").append(params.get("out_trade_no")) .append("\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"total_amount\":") .append(params.get("total_amount")).append(",\"subject\":\"").append(params.get("subject")) .append("\"}"); // 对所有待发送的数据项做统一加密处理 boolean signResult = AlipaySignature.rsaCheckV1(params, publicKey, charset, signType); if (!signResult) { throw new RuntimeException("Sign Check Failed!"); } return AlipayClient.execute(orderInfo.toString()); } } ``` 值得注意的是,在这段示例性的片段当中已经省略掉了部分细节内容,比如关于如何动态组装商品列表结构体之类的辅助函数定义等等[^3]。 另外一方面,考虑到目标运行载体为轻量级前端容器而非传统的Web浏览器页面,则还需要额外关注几个方面的问题: - 小程序内部并不支持直接发起HTTP(S)网络请求,所以应当考虑引入第三方中间件充当代理服务器的角色负责转发消息往来; - 同样由于跨域资源共享策略(CORS)等因素的影响,建议尽可能减少前后两端之间的交互次数从而降低潜在风险发生的概率; - 如果涉及到敏感数据传输的话务必采取适当措施加以防护,例如但不限于SSL/TLS连接建立前后的双向认证机制或是HTTPS协议下的严格同源政策遵循情况检查等。 最后但同样重要的环节在于确保所编写的脚本能够在真实的物理硬件之上正常运作之前就已经过充分严格的单元测试覆盖率达到预期标准以上再行发布上线。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小Ti客栈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值