首先简单说一下流程:
1. android或ios通过java或其他后台服务端语言获取一个签名字符串orderinfo(支付宝提供了jar和demo)
2.android或ios获取到orderinfo后通过支付宝提供的SDK直接就可以调起支付宝支付界面
3.通过支付宝支付页面付款完成后,支付宝服务会异步通知到我们自己的服务端,并返回必要参数;这个接口需要我们后台
开发人员自己动手完成,根据支付宝返回的参数验签,根据返回状态,操作我们自己的数据库(比如更新订单状态为已付 款, 更新余额等等),需要注意的是支付宝异步回调接口只能返回字符串success或fail。如果返回fail支付宝会在接下来的 25小时以内完成8次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h);
4.万事大吉。
具体步骤:
移动端我不太会略过,我只说java服务端
1.通过蚂蚁金服开通支付宝商户号,并完成app支付签约;
2.得到appid,app_private_key(自己开发的应用私钥),alipay_public_key(支付宝公钥:用自己app的公钥换取到);
3.有这几个参数就可以写创建订单生成orderstr接口了;
4.自己手写异步回调接口不能有任何参数,可以用request直接获取响应参数
5.请看代码,只需将我的代码融入到你的框架中就大功告成了
第一步在pom中配置支付宝封装的jar包
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.3.87.ALL</version>
</dependency>
没有使用maven直接到蚂蚁金服去下载
第二步 填写你的参数
// 商户appid
public static final String APPID = "";
//app端支付宝支付异步通知结果;服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定 //义参数,必须外网可以正常访问
public static final String notify_url = "";
// 支付完成跳转页面
public static final String return_url = "";
// 请求网关地址
public static final String URL = "https://openapi.alipay.com/gateway.do";
// 编码格式
public static final String CHARSET = "UTF-8";
// 返回格式
public static final String FORMAT = "json";
// 支付宝公钥
public static final String ALIPAY_PUBLIC_KEY = "";
//应用私钥
public static final String APP_PRIVATE_KEY = "";
// RSA2
public static final String SIGNTYPE = "RSA2";
第三步 获取orderstr的方法
public Map createPayOrder(PayPaymentOrder payPaymentOrder,String return_url) {
String orderStr = "";
Map<String, String> resultMap = new HashMap<String, String>();
try {
//实例化客户端
/*
* 开放平台SDK封装了签名实现,只需在创建DefaultAlipayClient对象时,
* 设置请求网关(gateway),应用id(app_id),应用私钥(private_key),编码格式(charset),支付宝公钥(alipay_public_key),签名类型(sign_type)即可,
* 报文请求时会自动进行签名
* */
AlipayClient client = new DefaultAlipayClient(URL, APPID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY,SIGNTYPE);
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
// model.setBody(orderMap.get("body")); //商品信息
model.setSubject(payPaymentOrder.getPaySubject()); //商品名称
model.setOutTradeNo(payPaymentOrder.getPayOutTradeNo()); //商户订单号
// model.setTimeoutExpress(orderMap.get("timeout_express")); //交易超时时间
model.setTotalAmount(payPaymentOrder.getPayTotalAmt().toString()); //支付金额
model.setProductCode("FAST_INSTANT_TRADE_PAY"); //销售产品码
// model.setSellerId(UID); //商家id
ali_request.setBizModel(model);
ali_request.setNotifyUrl(notify_url); //App支付异步回调地址
// ali_request.setReturnUrl(return_url); //付款完成跳转页面
ali_request.setReturnUrl(return_url); //付款完成跳转页面
AlipayTradeAppPayResponse response = client.sdkExecute(ali_request);
orderStr = response.getBody();
if(StringUtil.isNullOrEmpty(orderStr)){
resultMap.put("status","1");
resultMap.put("msg","订单生成失败");
return resultMap;
}
List payOrderList = payPaymentOrderService.queryPayPaymentByNo(payPaymentOrder.getPayOutTradeNo());
if(payOrderList.isEmpty() || payOrderList.size() == 0){
payPaymentOrderService.savePayPaymentOrder(payPaymentOrder);
}
resultMap.put("orderStr",orderStr);//就是orderString 可以直接给客户端请求,无需再做处理。
resultMap.put("status","0");
resultMap.put("msg","订单生成成功");
log.info("支付宝App支付:支付订单创建成功out_trade_no----",payPaymentOrder.getPayOutTradeNo());
} catch (Exception e) {
resultMap.put("status","1");
resultMap.put("msg","订单生成失败");
log.info("支付宝App支付:支付订单生成失败out_trade_no----",payPaymentOrder.getPayOutTradeNo());
}
return resultMap;
}
第四步 异步回调的方法
public String notify(Map<String, String[]> requestParams,String tradeStatus) {
Map<String, String> params = new HashMap<String, String>();
for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = iter.next();
String[] values = requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
}
// 乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
// valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
params.put(name, valueStr);
}
log.info("app支付异步回调获取支付宝响应参数",params);
//3.签名验证(对支付宝返回的数据验证,确定是支付宝返回的)
boolean signVerified = false;
try {
//3.1调用SDK验证签名
/**
@param params 参数列表(包括待验签参数和签名值sign) key-参数名称 value-参数值@param publicKey 验签公钥
@param charset 验签字符集
**/
signVerified = AlipaySignature.rsaCheckV1(params,ALIPAY_PUBLIC_KEY, CHARSET, SIGNTYPE);
} catch (AlipayApiException e) {
e.printStackTrace();
log.info("支付宝App支付异步回调:验签异常");
}
//4.对验签进行处理
if (signVerified) { //验签通过
if(tradeStatus.equals("TRADE_SUCCESS")) {
//更新商品订单和交易订单状态,插入交易流水记录,更新账户余额
int returnResult = this.operaAmt(params,"01");
if(returnResult>0){
return "success";
}else{
return "fail";
}
}else{
return "fail";
}
} else { //验签不通过
log.info("支付宝App支付异步回调:验签失败");
return "fail";
}
}
测试方法
1.沙箱环境,官网有
2.正式环境测试技巧
1.首先内网穿透(因为支付宝异步回调咱们的接口需要外网能访问到);
安装nodejs,然后执行 npm install -g localtunnel;
启动命令 :lt -s <个性前缀> -p <要映射的端口>
2.把穿透的路径拼接到异步回调地址上;
3.android或ios可以直接发送请求从本地服务获取orderstr;
备注:只要能获取正确的orderstr就能调起支付界面;
初次尝试写博客:请多多指教可以留下联系方式多多沟通;