上海网站建设服务宁德,国外wordpress商城,自己做网站的成本要哪些东西,规划网站开发总体方案一 什么是沙箱#xff1a;
沙箱环境是支付宝开放平台为开发者提供的安全低门槛的测试环境
支付宝正式和沙箱环境的区别 #xff1a;
AI#xff1a; 从沙箱到正式环境#xff1a; 当应用程序开发完成后#xff0c;需要将应用程序从沙箱环境迁移到正式环境。 这通常涉及…一 什么是沙箱
沙箱环境是支付宝开放平台为开发者提供的安全低门槛的测试环境
支付宝正式和沙箱环境的区别
AI 从沙箱到正式环境 当应用程序开发完成后需要将应用程序从沙箱环境迁移到正式环境。 这通常涉及到更新应用程序中的配置文件更换正式的 AppID 和密钥等凭证。
二 注册使用
网址登录 - 支付宝 点击 进行注册 查看信息appid 点击查看 应用密钥与支付宝公钥 appPrivateKey 与 publiceKey 记录一下卖家信息
三 实现
支付实现的步骤1.导入依赖 2.配置参数 3.调用方法API调用 4.处理响应或异常
具体实现可查看官网文档 小程序文档 - 支付宝文档中心
小程序文档 - 支付宝文档中心 简易版概述小程序文档 - 支付宝文档中心
小程序文档 - 支付宝文档中心
查看api使用规范 根据需求选择对应的接口方法 比如下面我们要实现的电脑网站的支付功能
对应的就是 Factory.Payment.Page.pay()
Easy 版
有拦截器的 注意放开路径
3.1 导入项目依赖
!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-easysdk --
dependencygroupIdcom.alipay.sdk/groupIdartifactIdalipay-easysdk/artifactIdversion2.2.0/version
/dependency3.2 编写配置信息
其中关于//PostConstruct 是一个 Java 注解用于标记需要在依赖注入完成后执行的方法。它表示该方法应该在对象创建和属性注入完毕后由容器自动调用以完成初始化工作。
Component
ConfigurationProperties(prefix alipay)
Datapublic class AlipayConfig {// 应用Idprivate String appId;// 应用私钥private String appPrivateKey;// 支付宝公钥private String publiceKey;// 回调接口路径private String notifyUrl;// 支付宝网关地址private String gatewayHost;PostConstruct//PostConstruct 是一个 Java 注解用于标记需要在依赖注入完成后执行的方法。// 它表示该方法应该在对象创建和属性注入完毕后由容器自动调用以完成初始化工作。// 此注解的方法无参数返回类型可为空或其他类型。主要用于确保对象完全初始化。public void init(){Config config new Config();// 基础配置config.protocol https;config.gatewayHost this.gatewayHost;// 支付宝网关地址config.signType RSA2;// 业务配置config.appId this.appId;config.merchantPrivateKey this.appPrivateKey;config.alipayPublicKey this.publiceKey;config.notifyUrl this.notifyUrl;// 将配置信息 添加到相应的工厂类Factory.setOptions(config);System.out.println(支付宝初始化配置完成);}
}application.properties
其中 appid appPrivateKey publiceKey 在开发者平台获取
gatewayHost 大家都一样 无需更改
notifyUrl 是内网穿透这里使用不到 现在随便写都可以
alipay.appid9021000139682312
alipay.appPrivateKeyMIIEvwIBADANBgkqhkiG9w0BAQEFAAS...
alipay.publiceKeyMIIBIjANBgkqhkiG9w0BAQEFAAOC.......
alipay.notifyUrlhttp://xxxxxxx/api/alipay/notify
alipay.gatewayHostopenapi-sandbox.dl.alipaydev.com3.3 调用支付方法
我这里直接在cotroller层编写
RestController
RequestMapping(/api/alipay)
public class PayController {/*** 订单支付接口 核心是调用支付宝的 Factory.Payment.Page().pay() 方法* param subject 支付对象信息* param outTradeNo 订单号* param totalAmount 订单金额* param returnUrl 支付成功以后返回的页面地址* return*/GetMapping(/pay)public void pay(String subject, String outTradeNo, String totalAmount, String returnUrl, HttpServletResponse httpResponse) throws Exception {// 使用支付宝支付页面接口进行支付AlipayTradePagePayResponse response Factory.Payment.Page().pay(subject, outTradeNo, totalAmount, returnUrl);System.out.println(response);// response.getBody();// 设置HTTP响应内容类型为HTML编码为UTF-8httpResponse.setContentType(text/html;charsetutf-8);// 向HTTP响应写入支付宝支付页面接口返回的响应体httpResponse.getWriter().write(response.getBody());// 刷新HTTP响应输出流确保数据立即发送到客户端httpResponse.getWriter().flush();// 关闭HTTP响应输出流释放资源httpResponse.getWriter().close();}}Java
可以进行测试后端了
可以进行测试后端了
可以进行测试后端了 http://localhost:8080/api/alipay/pay?subject%E7%81%AB%E8%BD%A6%E7%A5%A8%E6%94%AF%E4%BB%98outTradeNo63172637totalAmount16.8returnUrlhttp%3A%2F%2Flocalhost%3A8080%2Fpayok.html%3ForderId%3D312323 3.4 回调方法 配合内网穿透使用
回调就是支付宝在进行扣款操作之后 调用我们的后端 告诉我们支付结果
回调方法如下
回调中有个验证操作来源于调用官方给我们提供的方法来验证数据的真实性。 PostMapping(/notify)public String notify(RequestParam Map parameterMap) throws Exception {String tradeStatus parameterMap.getOrDefault(trade_status,).toString();if (tradeStatus.trim().equals(TRADE_SUCCESS)) {// 验证请求的有效性if (Factory.Payment.Common().verifyNotify(parameterMap)) {System.out.println(通过支付宝的验证);System.out.println(订单id parameterMap.get(out_trade_no));}else {System.out.println(支付验证不通过);}}return success;} 需要先开启内网穿透
服务器为localhost:8080 支付宝无法调用
注意如果是部署云服务器就不需要内网穿透了 只不过需要我我们对回调的参数进行相对应的修改
3.5 内网穿透工具
1.路由侠-局域网变公网 设置 信息 主机号 查看内网映射 测试 说明映射是没有问题的 成功调用了后端 修改 alipay.notifyUrl 的 配置信息 alipay.notifyUrlhttp://xxxk.w1.luyouxia.net/api/alipay/notify 再次进行支付测试s
这里加上vue进行测试
前端 vue
3.6 前端
templateh2支付/h2el-form :inlinetrue :modelform classdemo-form-inlineel-form-item label支付对象信息el-input v-modelform.subject placeholder请输入 clearable //el-form-itemel-form-item label订单号el-input v-modelform.outTradeNo placeholder请输入 clearable //el-form-itemel-form-item label订单金额el-input-number v-modelform.totalAmount placeholder请输入 clearable //el-form-itemel-form-item label支付成功以后返回的页面地址el-input v-modelform.returnUrl placeholder请输入 clearable //el-form-itemel-form-itemel-button typeprimary clickonSubmit提交/el-button/el-form-item/el-formbrh2退款/h2el-form :inlinetrue :modelform2 classdemo-form-inlineel-form-item label退款单号el-input v-modelform2.outTradeNo placeholder请输入 clearable //el-form-itemel-form-item label退款金额el-input-number v-modelform2.refundAmount placeholder请输入 clearable //el-form-itemel-form-itemel-button typeprimary clickonSubmit2提交/el-button/el-form-item/el-form
/template
script setup langts
import { onMounted, ref } from vue;
import dayjs from dayjs;
import router from /router;
import { ElNotification } from element-plus
import { alipayApi } from /api;
const form ref({subject: 小米su8,outTradeNo: dayjs().format(YYYYMMDDHHmmss),totalAmount: 188888,returnUrl: http://localhost:5000/paysuccess
})const form2 ref({outTradeNo: 20220422164101,refundAmount: 18888,
})
const onSubmit () {let returnUrl encodeURIComponent(form.value.returnUrl)window.location.href http://localhost:8080/api/alipay/pay?subject ${form.value.subject} outTradeNo ${form.value.outTradeNo} totalAmount ${form.value.totalAmount} returnUrl ${returnUrl}
}
const onSubmit2 () {alipayApi.refund.call({outTradeNo: form2.value.outTradeNo,refundAmount: form2.value.refundAmount}).then(_res {ElNotification({title: 提示,message: 退款成功,type: success,})})
}/script
测试结果
一方面 前端返回我们设置的 returnUrl 界面
另一方 后端执行 配置的 alipay.notifyUrlhttp://xxxk.w1.luyouxia.net/api/alipay/notify
成功
3.7 退款 调用 refund 交易退款方法 GetMapping(/refund)public String refund( String outTradeNo,Float refundAmount) {try {
com.alipay.easysdk.payment.common.models.AlipayTradeRefundResponse response Factory.Payment.Common().refund(outTradeNo, String.valueOf(refundAmount));System.out.println(response);if (response.msg.equals(Success)){return 退款成功;}else {throw new BizException(777, 退款失败);}}catch (Exception e){e.printStackTrace();throw new BizException(777, 退款失败);}}通用版
小程序文档 - 支付宝文档中心
通用版
导入依赖 dependencygroupIdcom.alipay.sdk/groupIdartifactIdalipay-sdk-java/artifactIdversion4.34.0.ALL/version/dependency 配置
Component
ConfigurationProperties(prefix alipay2)
Data
public class Alipay2Config extends com.alipay.api.AlipayConfig {// 网关地址private String serverUrl;// 应用Idprivate String appId;// 应用私钥private String appPrivateKey;//请求格式private String format;//字符集编码private String charset;//签名类型private String signType;// 支付宝公钥private String publiceKey;// 回调接口路径private String notifyUrl;}支付 GetMapping(/pay2)public void pay2(String subject, String outTradeNo, String totalAmount, String returnUrl, HttpServletResponse httpResponse) throws Exception {AlipayClient alipayClient new DefaultAlipayClient(alipay2Config.getServerUrl(), alipay2Config.getAppId(),alipay2Config.getAppPrivateKey(), alipay2Config.getFormat(), alipay2Config.getCharset(), alipay2Config.getAlipayPublicKey(), alipay2Config.getSignType());AlipayTradePagePayRequest request new AlipayTradePagePayRequest();request.setNotifyUrl(alipay2Config.getNotifyUrl());request.setReturnUrl(returnUrl);JSONObject bizContent new JSONObject();bizContent.put(out_trade_no, outTradeNo);bizContent.put(total_amount, totalAmount);bizContent.put(subject, subject);bizContent.put(product_code, FAST_INSTANT_TRADE_PAY);request.setBizContent(bizContent.toString());String form ;try {// 调用SDK生成表单form alipayClient.pageExecute(request).getBody();} catch (AlipayApiException e) {e.printStackTrace();}httpResponse.setContentType(text/html;charsetUTF-8);// 直接将完整的表单html输出到页面httpResponse.getWriter().write(form);httpResponse.getWriter().flush();httpResponse.getWriter().close();}退款 /*** 退款接口** return*/GetMapping(/refund2)public String refund2 (String outTradeNo, Float refundAmount){AlipayClient alipayClient new DefaultAlipayClient(https://openapi-sandbox.dl.alipaydev.com/gateway.do,alipayConfig.getAppId(),alipayConfig.getAppPrivateKey(),JSON,utf-8,alipayConfig.getPubliceKey(),RSA2);AlipayTradeRefundRequest request new AlipayTradeRefundRequest();// 获取获取对应订单信息JSONObject bizContent new JSONObject();bizContent.put(out_trade_no, outTradeNo);bizContent.put(refund_amount, refundAmount);bizContent.put(out_request_no, HZ01RF002); //退款标识用于查询状态是操作request.setBizContent(bizContent.toString());// 使用支付宝支付页面接口进行支付try {AlipayTradeRefundResponse response alipayClient.execute(request);System.out.println(response);if (response.isSuccess()) {System.out.println(退款成功);return 退款成功;} else {System.out.println(退款失败);throw new BizException(777, 退款失败);}} catch (Exception e) {e.printStackTrace();System.out.println(退款失败);throw new BizException(777, 退款失败);}}