java实现支付宝网页扫码支付
接口文档
https://docs.open.alipay.com/270
1.注册自由开发者身份
2.打开开发中心![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UF8prDqn-1604249305004)(image\1566459805321.png)]
2.选择沙箱操作[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UwXLO2Jo-1604249305006)(image\1566460201043.png)]
3.点击设置公钥
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6I83QCDl-1604249305008)(image\1566460270289.png)]
4.查看密钥生成方法,选择版本下载密钥生成器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yxojqKgV-1604249305010)(image\1566460341470.png)]
5.解压并按说明文档操作[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EdyhhRo9-1604249305011)(image\1566460386012.png)]
6.如图所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sime20ES-1604249305013)(image\1566460523406.png)]
7.设置密钥
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hfNNp7Oq-1604249305014)(image\1566460621536.png)]
将生成的公钥复制粘贴到设置公钥处[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1OW1qIpx-1604249305014)(image\1566460661502.png)]
8.下载沙箱版支付宝,登陆买家账号
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rVzOedNC-1604249305015)(image\1566460797509.png)]
新建springcloud工程
1.导入依赖
com.alipay.sdk
alipay-sdk-java
3.3.49.ALL
2.创建配置信息类,其中配置信息为在沙箱环境中配置的密钥等信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9GSSGxcp-1604249305016)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1566462078852.png)]
package com.alipay.config;
import java.io.FileWriter;
import java.io.IOException;
/* *
*类名:AlipayConfig
*功能:基础配置类
*详细:设置帐户有关信息及返回路径
*修改日期:2017-04-05
*说明:
*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
public class AlipayConfig {
//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
public static String app_id = "2016101400681640";
// 商户私钥,您的PKCS8格式RSA2私钥
public static String merchant_private_key = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCPLoHDYEr++A495u5HgDq8K5eEu45ctoAci/veJEwI2q+UveqUEB9ne6hwUtx85iJM8c7CfGmwQSwH+lctQE3OzenCBr/jRvmD+4CAE7aO09Bpc054Jftk5hGNHdESgj1PMSIIDkDdnJMjhEsi5ogY675gcTA6vPsDRGNgCfa/L+qLnnafkRcqKZngK/NQ56iOdFWFE7eJrJgrOaB9FNJg4wV0Dcvkp8ya9EAbas3dc4gLVzt7xYZzY5ALvnJTbfOCgD22sjf0+ZKGNH1TrzxNX6RiYE3q+tEnj/3G4v1kpY1nwmwCjKuBcFk2rGEZpSjqKDLUtNz0o+odlLrS8xVVAgMBAAECggEAW/tulYso4r+MtqvCa+Cu2u/OOREclecQSkaLmdwLlKyYm5+eMVxiMGK6hN5Wk05svq2hPEQcyYQ0uzNSCdoDolWaVHFtmJ6h8O4DUURYxUzB2NygjoMoC1vZ7qQ3CgLtTBCuYip19Wh/BhQZCOS8jfX0qZRNfY6mWyT2Cl6cS5mIWCmwbo4roGmQ2OxwOkDLifCc2RF5eCvQpzOs/jpP4UoXmJt1rlRBMGneegwS3FVzanqlh7ssmOShFU5gsJcDjv2eJVmiuQ97ztb0wdT3ZWn9l/9rFR+SPyBadubGomKeOcoEbJYmZtsMr7/YPsHNsdtiYirSqvordXz/ZcJeQQKBgQD4e4FeDM+gjwtTcmJ5Bf7+1YFzhK6oqWGXUcZ8wnE2jC2luNi/JvwheCBt905KjTVsXndQgXx8ZtuLD8q35pkEuE13L3lAMrzUv48LcwAP6LXY9Nb2iLIood0fHd/Ios1uEJtkzugPqxZF7ESx79eeHM9S4OJFw79rfnhdDzT27QKBgQCTg3KlBLyPs9vImLtNnwtPjofNCbt+rID+LhNlMSbWN87k9loEbJHUVVAvdvLIgbk9Ok5Z8aiu3aS4LRLJjCXjI76PAfO8MLGgg8ff+mHMS439FMFlj270+U8j7veFsYEkxh6ciNCTon0gP9V8RB5vHR3LpXl4WiAOZwWSPyQjCQKBgQCmgbxy1YrcQH6KcH/kMUxqX4/bZPHVO4uV5spnF7TdpJmCD5fOn8UceG7iwXHJK069S6AQZnSQuCwtx2tESFYJf6cJUtqhVl6LAcJNHcbQ4lPZClhx46/e4nhWPaKTw+R8+MvohW2j8jV+rZBq3BlUbmHPW7rEnSNMWPc3BNWtEQKBgE7Odrz6HtKWv+AW2FnLkftapepAPM6b0f35F5uD+r+O6RUhF04twmqxeTkiTuoXg6LWN22N0RQ6jPln+xV5rfP+8Jrt7Ayp5vtd67YYyY6e/qgqInfjfN+bIVCNJediwR+oSEpQPT3iHP7Rm3fb3HZ4E6bsLEzDuUR4fV14JhIhAoGBALUg0eY0ODMfCtvmg5Zp4fEW5GJOM2aQmxiZj0RMLByfgKsYWD+mn/eEMDgaT6KGc/MsUQo//402ZOCM4TXNrPaKYyNkyqLfyhl3KibooPNB5DPGsj0ff4MQxfryPlT24sDBNZmMSUzMVqYVdRZSM5Ersdmu+vZ7bTZio3Q3Ym96";
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
public static String alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlz9GS8eINNVDD0t4ervFT+ifYaq1gPPpNHJXOpTeEEeNPYa6WO5ahvjtcydzvZot3nuWwlj4qBIgQLxbkShHoTzXqsvS0fkVmhtekcdcUp9zIGhf/woDeaDVsXXJ/NrCZa6DbQLMv5kF2ojI2Xa+Akon/uyn77SI1xOrWLOicLz+xje7s6VQ8JGh6a+JYc6Q7nprDLIKj1588PENsFrKFmbQS8lsqvr9LycKL1N1NpoUv6EWaelblCITAGCI4N6WBjLqwwbbZzpjNHxO54dAJndTyLgFt8KXKGMi+c0LOF6in265x7xYCL+R9v4X7RXuhHdFS/ouaCnMiAZIl747qwIDAQAB";
// 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
//public static String notify_url = "http://localhost:8080/pay/notify_url.jsp";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
//public static String return_url = "http://localhost:8080/pay/return_url.jsp";
// 签名方式
public static String sign_type = "RSA2";
// 字符编码格式
public static String charset = "utf-8";
// 支付宝网关
public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
// 支付宝网关
public static String log_path = "C:\\";
//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
/**
* 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
* @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();
}
}
}
}
}
3.创建请求方法,方法请求接口alipay.trade.page.pay ,参数说明文档https://docs.open.alipay.com/api_1/alipay.trade.page.pay
参数 | 类型 | 是否必填 | 最大长度 | 描述 | 示例值 |
---|---|---|---|---|---|
out_trade_no | String | 必选 | 64 | 商户订单号,64个字符以内、可包含字母、数字、下划线;需保证在商户端不重复 | 20150320010101001 |
product_code | String | 必选 | 64 | 销售产品码,与支付宝签约的产品码名称。 注:目前仅支持FAST_INSTANT_TRADE_PAY | FAST_INSTANT_TRADE_PAY |
total_amount | Price | 必选 | 11 | 订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]。 | 88.88 |
subject | String | 必选 | 256 | 订单标题 | Iphone6 16G |
body | String | 可选 | 128 | 订单描述 | Iphone6 16G |
time_expire | String | 可选 | 32 | 绝对超时时间,格式为yyyy-MM-dd HH:mm:ss | 2016-12-31 10:05:01 |
goods_detail | GoodsDetail[] | 可选 | 订单包含的商品列表信息,json格式,其它说明详见商品明细说明 | ||
passback_params | String | 可选 | 512 | 公用回传参数,如果请求时传递了该参数,则返回给商户时会回传该参数。支付宝只会在同步返回(包括跳转回商户网站)和异步通知时将该参数原样返回。本参数必须进行UrlEncode之后才可以发送给支付宝。 | merchantBizType%3d3C%26merchantBizNo%3d2016010101111 |
extend_params | ExtendParams | 可选 | 业务扩展参数 | ||
goods_type | String | 可选 | 2 | 商品主类型 :0-虚拟类商品,1-实物类商品 注:虚拟类商品不支持使用花呗渠道 | 0 |
timeout_express | String | 可选 | 6 | 该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m | 90m |
promo_params | String | 可选 | 512 | 优惠参数 注:仅与支付宝协商后可用 | {“storeIdType”:“1”} |
royalty_info | RoyaltyInfo | 可选 | 描述分账信息,json格式,详见分账参数说明 | ||
sub_merchant | SubMerchant | 可选 | 间连受理商户信息体,当前只对特殊银行机构特定场景下使用此字段 | ||
merchant_order_no | String | 可选 | 32 | 商户原始订单号,最大长度限制32位 | 20161008001 |
enable_pay_channels | String | 可选 | 128 | 可用渠道,用户只能在指定渠道范围内支付,多个渠道以逗号分割 注,与disable_pay_channels互斥 渠道列表:https://docs.open.alipay.com/common/wifww7 | pcredit,moneyFund,debitCardExpress |
store_id | String | 可选 | 32 | 商户门店编号 | NJ_001 |
disable_pay_channels | String | 可选 | 128 | 禁用渠道,用户不可用指定渠道支付,多个渠道以逗号分割 注,与enable_pay_channels互斥 渠道列表:https://docs.open.alipay.com/common/wifww7 | pcredit,moneyFund,debitCardExpress |
qr_pay_mode | String | 可选 | 2 | PC扫码支付的方式,支持前置模式和 跳转模式。 前置模式是将二维码前置到商户 的订单确认页的模式。需要商户在 自己的页面中以 iframe 方式请求 支付宝页面。具体分为以下几种: 0:订单码-简约前置模式,对应 iframe 宽度不能小于600px,高度不能小于300px; 1:订单码-前置模式,对应iframe 宽度不能小于 300px,高度不能小于600px; 3:订单码-迷你前置模式,对应 iframe 宽度不能小于 75px,高度不能小于75px; 4:订单码-可定义宽度的嵌入式二维码,商户可根据需要设定二维码的大小。 跳转模式下,用户的扫码界面是由支付宝生成的,不在商户的域名下。 2:订单码-跳转模式 | 1 |
qrcode_width | Number | 可选 | 4 | 商户自定义二维码宽度 注:qr_pay_mode=4时该参数生效 | 100 |
settle_info | SettleInfo | 可选 | 描述结算信息,json格式,详见结算参数说明 | ||
invoice_info | InvoiceInfo | 可选 | 开票信息 | ||
agreement_sign_params | AgreementSignParams | 可选 | 签约参数,支付后签约场景使用 | ||
integration_type | String | 可选 | 16 | 请求后页面的集成方式。 取值范围: 1. ALIAPP:支付宝钱包内 2. PCWEB:PC端访问 默认值为PCWEB。 | PCWEB |
request_from_url | String | 可选 | 256 | 请求来源地址。如果使用ALIAPP的集成方式,用户中途取消支付会返回该地址。 | https:// |
business_params | String | 可选 | 512 | 商户传入业务信息,具体值要和支付宝约定,应用于安全,营销等参数直传场景,格式为json格式 | {“data”:“123”} |
ext_user_info | ExtUserInfo | 可选 | 外部指定买家 |
@Component
public class AlipayUtils {
public String pay() throws AlipayApiException {
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl,AlipayConfig.app_id,AlipayConfig.merchant_private_key,"json","utf-8",AlipayConfig.alipay_public_key,"RSA2");
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request
alipayRequest.setBizContent("{" +
" \"out_trade_no\":\"20150320013333\"," +
" \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
" \"total_amount\":88.88," +
" \"subject\":\"Iphone6 16G\"," +
" \"body\":\"Iphone6 16G\"," +
" \"passback_params\":\"merchantBizType%3d3C%26merchantBizNo%3d2016010101111\"," +
" \"extend_params\":{" +
" \"sys_service_provider_id\":\"2088511833207846\"" +
" }"+
" }");
String form="";
form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单 System.out.println(response.getBody());
return form;
}
}
4.创建controler层
@RestController
public class PayController {
@Autowired
private AlipayUtils alipayUtils;
@RequestMapping("/pay")
public String pay(){
String pay="";
try {
pay = alipayUtils.pay();
} catch (AlipayApiException e) {
e.printStackTrace();
}
System.out.println(pay);
return pay;
}
}
启动springboot启动类,访问localhost:8080/pay,使用沙箱钱包扫码支付,对比支付完成前后金额
} catch (AlipayApiException e) {
e.printStackTrace();
}
System.out.println(pay);
return pay;
}
}
启动springboot启动类,访问localhost:8080/pay,使用沙箱钱包扫码支付,对比支付完成前后金额
若金额不足,前往沙箱充值,想充多少充多少