说明:
由于没有商户账号,所以本文使用的是沙箱账号,本质跟真实账号是一样的,是支付宝为了方便开发人员开发调试而推出的策略。在真实开发中将商户公钥等修改为真实的商户即可。
支付基本流程
- 用户下单
- 商户账号(收款方)在配置中已经配置好,调用第三方接口根据用户提交的订单(应包括订单编号,订单名称,价格等信息)来生成支付流水单(可以是生成一个二维码也可以是普通的收款单),然后返回给前端显示给用户,等待用户支付。
- 用户扫码或者点击支付等完成支付。
- 第三方接口会检测到用户是否完成支付,然后返回一个结果到某个url(称为回调,url由开发者自定义),如果返回的结果是支付成功了,那么开发者可以给予用户某些提示,或者跳转页面,表示用户支付成功了。
沙箱环境准备
- 登陆支付宝开发者平台https://open.alipay.com/platform/developerIndex.htm
点击研发服务
2. 设置密钥
密钥需要用工具生成,工具地址:https://miniu.alipay.com/keytool/create
将工具生成的 “应用公钥”” 复制到如图应用公钥中,此时会自动生成支付宝公钥。
3. 获取沙箱账号(包括买家和买家)
点击右侧“沙箱账号”就可以看到账号信息
4. 下载沙箱版支付宝
用生成的买家账号来登陆,余额可以随便充值,后面扫码支付也是用这个账号。
扫码支付例子
- 需要的依赖
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.7.110.ALL</version>
</dependency>
- 创建一个配置类,由于调用第三方接口,用到的配置很多,所以用一个类来保存
import java.io.FileWriter;
import java.io.IOException;
public class AlipayConfig {
//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
public static String app_id ="2021000118610565";
// 商户私钥,您的PKCS8格式RSA2私钥
public static String merchant_private_key = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCgDHNYP0CgXrK5gYQk1VM+U8CIy4J58RkD4bRHATOkWSEONWFcMMr7zqHKEnHd0UJFoMk0zzXUN95+BCgcS5uh6o0KJEDMQLMgVI6UHesTeZYtH52TQ72BKLpcq9ooTwkMl4kyCOeM5PwN85b3P+89+HpXGSQ8Ew9VxR3J4WBDrs9jHx/x9hy7OowCCV7rawXU260ohUoi7dNi0kvugFLxmlvtGBlVG1/+hZar45jZ8GY1P4d7b1+fEGSGd9IVr49rCZjh5zR9pEYk3ogZoQL+qiqzMXIjH5aJ3pT/HHUsWnczsa9UU9lT29UpQmwULc/9gwbLHEhf8aHfnpgBuMnJAgMBAAECggEAJbJJCKP9SMiFOAQ1Z6eHL8ryMkYcuTP8PFnQ6Fh0HWWQz5PrFpe3d4+3s6ycfS5oeZXhTjrv5sgx82RvPhrg0UY5agYX7QPgLOE9o81YLQIaSQ6FQsZVwDIjkug3Pf8/lmOqwMowH5NfernA+QNqCiKYTiNx0WR73CvNVFttHQOT4X8DUTCoZhuycdO9b9GM+uzY+dkaSsmRRfd1CYXKsWhs9uSXjN0owcMx19XAy7oKaGF4MuYECsj+tpvownxyOboI9Ard/VNtvb93xNCykmu0XCiM6fte/7HNogZQpM1h64gNaWcCUhrk8ZUVI8HWxK/0H3DnH6BHN/sTtLxuMQKBgQDZzhwRYCo85U/UGEg62NbJDd4EAU0AQ4kH2inUWg9VlaSahRtglbYDDMOJyIV8xZBF6nHtgCZy4HIey/jLyYt4F8QMX4V2HQI6/Kp6mwp1Fnh3nJk90h4FAsWq56J8qe60esKWovNE5qT6aI5eTGp5xi58/E1jj2V1KBfqGLjWCwKBgQC8HX0KMBSOD5A5P21vG9EfcqT3yS8QsNOUSBlCSzkhEARgfz8FAz+W8Slpgz/7SKtihi2VZeuaq7HRPqpJqFTWiv3b4ceKGX6iY59c9pYqnO25D50pdhWnGmvyt/MxcUWjIVFk9TwIKy/4mN3eRKD/eEv3m6Ts5i8N/3cYUfHn+wKBgChfYCyIWsv25Zk29wyRbR7PhzvO0esemaPu+Jn4J6eBmYVa7vw0RAzErOo5VSUPqfKLxppziqz4la7HuFJuBYA5R4nTmvWN4v/0HdWkL4gMpj/lszIWZKIhJWrMjP32sdyadL9fbSB0cFhKUTmBiKsR5UQdsGqoBfJ1gBlQg9KJAoGBAKYfWHPtv8kwf0m+9JJBO20NHhff55tSvJXfEcdUjK/g6CybUnjHxJk0gUC3coIjS45nNcwQRH7DjvVc5J7Fc54/Ai3ydfdDymv3lB1ReY1KJjjeTAj4SejW0Wt3/OC1yixkWO/SDWCdWvCrdos5if/xKQ0RuxSltfojlvW4L+uPAoGAaj/dpqyS+dgu+coGC2y1EuilKZZ72AGt3W1/b4nU6FGlDTxeELZWGaMKTCP21hELJAV3WVzc9bj3dwHYMI+LxGqwkuDmmlBGvGD+QEBFKWK679z0wGTQBZOcAzPKvBxRV9LHA+2Bq8ixaoyYvwo/cFZBVvfm+NMWotUNGYTk/Ww=";
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
public static String alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoAxzWD9AoF6yuYGEJNVTPlPAiMuCefEZA+G0RwEzpFkhDjVhXDDK+86hyhJx3dFCRaDJNM811DfefgQoHEuboeqNCiRAzECzIFSOlB3rE3mWLR+dk0O9gSi6XKvaKE8JDJeJMgjnjOT8DfOW9z/vPfh6VxkkPBMPVcUdyeFgQ67PYx8f8fYcuzqMAgle62sF1NutKIVKIu3TYtJL7oBS8Zpb7RgZVRtf/oWWq+OY2fBmNT+He29fnxBkhnfSFa+PawmY4ec0faRGJN6IGaEC/qoqszFyIx+Wid6U/xx1LFp3M7GvVFPZU9vVKUJsFC3P/YMGyxxIX/Gh356YAbjJyQIDAQAB";
// 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String notify_url = "http://103.46.128.21:29069/result";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 return_url.jsp
public static String return_url ="http://103.46.128.21:29069/result";
// 签名方式
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();
}
}
}
}
}
- 创建一个controller来将二维码返回到前端显示
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class PayController {
@RequestMapping("/toPay")
@ResponseBody
public String toPay(String orderid,String price,String title) throws Exception {
//获得初始化的AlipayClient
AlipayClient 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);
try {
//发送请求参数 orderid 订单id,price表示价格,title表示订单标题
alipayRequest.setBizContent("{\"out_trade_no\":\"" + orderid + "\","
+ "\"total_amount\":\"" + price + "\","
+ "\"subject\":\"" + title+ "\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
//请求
String result;
result = alipayClient.pageExecute(alipayRequest).getBody();
return result;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
- 需要修改的配置
代码中是我的配置,你需要修改为自己的沙箱账号等信息。
① app_id
② merchant_private_key
③alipay_public_key
分别对应应用私钥和应用公钥
④notify_url
回调地址,你可以自定义,但是第三方接口会将支付结果返回到这个地址上,所以这个地址需要公网能访问,如果在本地测试,可以使用 “花生壳” 这个软件来做内网穿透(内网穿透就是原本两台pc机只有在同一个局域网下才能互相访问,在公网下是不能访问的,做了内网穿透之后就可以使公网能访问)。
测试
运行程序访问8080端口的toPay
再使用沙箱账号登陆沙箱支付宝扫码支付即可。