支付寶線下門店掃碼支付開發
阿新 • • 發佈:2019-02-06
支付寶掃碼支付
一.開發前準備
https://doc.open.alipay.com/doc2/detail.htm?spm=0.0.0.0.B6xA20&treeId=26&articleId=103239&docType=1
1.開通支付寶企業號
2.簽約認證
3.建立應用,稽核通過。
4.上傳應用公鑰。
二.開發demo從支付寶官網下載
alipay-sdk-Java-ALL20150604113758-source.jar
alipay-sdk-java-ALL20150604113758.jar
/** * 呼叫支付寶掃碼支付二維碼生成 * * @return */ public String aliQr() { String orderId = httpServletRequest.getParameter("orderId"); String out_trade_no = getTradeNo(); String total_amount = httpServletRequest.getParameter("total_amount"); String subject = ""; String companyId = getCompanyInfo().getCompanyId(); Order o = null; try { o = orderService.getOrderById(Integer.parseInt(orderId)); subject = CommonCompanyName(o.getCompanyId(), o.getSubCompanyId()) + "的商品" + total_amount + "元"; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } AlipayTradePrecreateResponse response = qrPay(out_trade_no, total_amount, subject, companyId, orderId, o.getSubCompanyId()); if (null != response && response.isSuccess()) { ResponseWriteUtil.writeHTML("{\"code\":\"" + response.getQrCode() + "\"," + "\"outTradeNo\":\"" + response.getOutTradeNo() + "\"}"); // 生成自定義二維碼圖片 // String path = "/qrcode/" + companyId + "/" + out_trade_no + // ".png"; // String qrCodePath = ServletActionContext.getServletContext() // .getRealPath(path); // ZXingQrCode.createQrCodeImg(300, 300, response.getQrCode(), // qrCodePath); // 儲存二維碼值 HashMap<String, Object> map = new HashMap<String, Object>(); map.put("orderId", orderId); map.put("aliqrcodeUrl", response.getQrCode()); // map.put("aliqrcodeUrl", ConfigUtil.SYS_BASE_URL + path); orderService.updateAliQrCodeByOrderId(map); } else { ResponseWriteUtil.writeHTML("{\"code\":\"0\"}");// 不存在 } return null; } public String CommonCompanyName(String companyId, String subCompanyId) { Seller seller = sellerService.findSellerByCompanyId(companyId); String commonMsg = ""; SubCompany subCompany = null; if (StringUtils.isNotBlank(subCompanyId)) { subCompany = subCompanyService.fetchSubCompanyBySid(subCompanyId); } if (subCompany == null) {// 主店 commonMsg = seller.getCompanyName(); } else {// 分店 commonMsg = subCompany.getCompanyShortName(); } return commonMsg; } /** * 是否配置了支付寶二維碼支付 * * @return */ public String isExistByAliPayQrCode() { String companyId = httpServletRequest.getParameter("companyId"); String subCompanyId = httpServletRequest.getParameter("subCompanyId"); HashMap<String, Object> map2 = new HashMap<String, Object>(); map2.put("companyId", companyId); map2.put("subCompanyId", subCompanyId); ALIPayConfigure aliPayConfigure = aliPayConfigureService .selectAppId(map2); if (aliPayConfigure != null) { ResponseWriteUtil.writeHTML("{\"code\":\"" + 1 + "\"}"); } else { ResponseWriteUtil.writeHTML("{\"code\":\"" + 0 + "\"}"); } return null; }
/** * 回撥通知處理 * * @return */ public String notifyMsgByAliPay() { String orderId = httpServletRequest.getParameter("orderId"); String totalAmount = httpServletRequest.getParameter("totalAmount"); String outTradeNo = httpServletRequest.getParameter("outTradeNo"); System.out.println("訂單號:" + orderId + ",訂單金額:" + totalAmount + ",商戶交易號:" + outTradeNo); System.out.println("支付寶非同步回撥通知:"); // 判斷付款是否成功,已成功則不再記錄付款資訊 if (orderService.ifOrderPaid(Integer.parseInt(orderId)) > 0) { log.info("付款已成功,不再記錄付款資訊"); ResponseWriteUtil.writeHTML("success"); return null; } aliPayService.aliPayFinsh(Integer.parseInt(orderId), totalAmount, outTradeNo); System.out.println("系統訂單業務處理完成"); ResponseWriteUtil.writeHTML("success");// 告訴支付寶我已處理,不需要重複發非同步通知 System.out.println("支付寶非同步回撥通知成功結束"); return null; }
js頁面
//*************start*********aliPayByQr****************************** //是否配置了支付寶掃碼 function isExistByAliPayQrCode(){ var companyId=$("#companyId").val(); var subCompanyId=$("#subCompanyId").val(); if(subCompanyId==null||subCompanyId=='null'||subCompanyId==undefined){ subCompanyId=""; } $.ajax({ url : '<%=basePath%>/aliPay!isExistByAliPayQrCode.action?companyId='+companyId+'&subCompanyId='+subCompanyId, async : false, type : "post", dataType : "json", success : function(result) { if(result.code!='0'){ $("#aliQrBtn").show(); }else{ $("#aliQrBtn").hide(); layer.msg("商家沒有配置支付寶掃碼支付!"); } } }); } function aliQrClick(){ var total_amount=$("#paymentAmount").val(); var orderId=$("#myorderId").val(); //check var paySize=$(".payMoneyC").length; var ptypeNum=$(".ptype:checked").length; var paySum=0; if(ptypeNum<=0){ layer.msg("支付方式至少選擇一個!"); return; } if(ptypeNum!=1){ layer.msg("支付方式只能是支付寶掃碼支付!"); return; } var companyId=$("#companyId").val(); var subCompanyId=$("#subCompanyId").val(); if(subCompanyId==null||subCompanyId=='null'||subCompanyId==undefined){ subCompanyId=""; } $.ajax({ url : '<%=basePath%>/aliPay!aliQr.action', async : false, type : "post", dataType : "json", data:{"total_amount":total_amount,"orderId":orderId}, success : function(result) { if(result.code!='0'){ $("#aliQrBtn").hide(); $("#outputALIQr").show(); <span style="color:#ff0000;">jQuery('#outputALIQr').qrcode({width:200,height:200,text:result.code});//</span><span style="color: rgb(255, 0, 0); font-family: Arial, Helvetica, sans-serif;">js</span><span style="color: rgb(255, 0, 0); font-family: Arial, Helvetica, sans-serif;">二維碼生成</span><span style="color:#ff0000;"> </span> window.setInterval(finshAliQrPay, 8000); }else{ layer.msg("支付寶二維碼生成出錯!"); } } }); } function qrQueryRetry(out_trade_no){ $.ajax({ url : '<%=basePath%>/aliPay!aliQueryRetry.action', async : false, type : "post", dataType : "json", data:{"out_trade_no":out_trade_no}, success : function(result) { } }); } var aliNum=0; function finshAliQrPay(){ var orderId=$("#myorderId").val(); $.ajax({ url : '<%=basePath%>/aliPay!<span style="color:#cc0000;background-color: rgb(255, 255, 255);">notifyOrderCashFinshed</span>.action?orderId='+orderId, async : false, type : "post", dataType : "json", data:$('#finishForm').serialize(), success : function(result) { if(result.code!='0'){ layer.msg("支付寶掃碼支付交易成功,訂單3秒後即將關閉!"); window.setTimeout(function(){ //關閉彈出窗之前,跳轉到其他頁面 parent.window.location.href="<%=path%>/"+result.redirectUrl; closeLayerDialog(); },3000); }else{ aliNum=aliNum+1; $("#aliQrPayNotifyNum").val(aliNum); } } }); } //*************end*******aliPayByQr********************************
5.aliPayService 實現類
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
@Service("aliPayService")
public class ALIPayServiceImpl implements ALIPayService {
Logger log = Logger.getLogger(ALIPayServiceImpl.class);
@Resource
private OrderDAO orderDAO;
@Resource
private SerialNumMngDAO serialNumMngDAO;
@Resource
private ALIPayTradeLogsDAO aliPayTradeLogsDAO;
@Resource
private ALIPayConfigureDAO aliPayConfigureDAO;
@Resource
private ALIPayTradeLogsService aliPayTradeLogsService;
@Resource
private ALIPayConfigureService aliPayConfigureService;
@Resource
private OrderService orderService;
@Override
public void aliPayFinsh(Integer orderId, String totalAmount,
String outTradeNo) {
// TODO Auto-generated method stub
Order o = null;
float paymentAmount = Float.parseFloat(totalAmount);
try {
o = orderDAO.getOrderbyId(orderId);
// 系統交易流水記錄
List<OrderPlus> ops = new ArrayList<OrderPlus>();
OrderPlus op = new OrderPlus();
op.setOrderId(o.getId());
op.setOrderAmount(o.getAmount());
op.setPaymentAmount(paymentAmount);
op.setPaymentTime(new Date());
op.setPaymentType(EnumUtil.PAYMENT_TYPE.alipayqrbycompay.getCode());
op.setNotes("支付寶掃碼支付:支付金額為" + paymentAmount);
ops.add(op);
orderDAO.insertOrderPlusPitch(ops);
// 更新系統訂單業務
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("orderId", o.getId());
// 外賣
if (o.getIsTakeOut() == 1) {
map.put("dealSts", EnumUtil.ORDER_dealSts.finished.getCode());
} else {
map.put("dealSts", EnumUtil.ORDER_dealSts.paid.getCode());
}
map.put("finishTime", new Date());
map.put("paymentAmount", paymentAmount);
map.put("orderPersonNum", 0);
map.put("orderTime", o.getOrderTime());
serialNumMngDAO.finishOrder(map);
// 支付寶交易流水記錄
HashMap<String, Object> map2 = new HashMap<String, Object>();
map2.put("companyId", o.getCompanyId());
map2.put("subCompanyId", o.getSubCompanyId());
ALIPayConfigure alipc = aliPayConfigureDAO.selectAppId(map2);
ALIPayTradeLogs aliPaytl = new ALIPayTradeLogs();
aliPaytl.setOutTradeNo(outTradeNo);
if (alipc != null) {
aliPaytl.setAppId(alipc.getAppId());
}
aliPaytl.setOrderId(String.valueOf(orderId));
aliPaytl.setTotalAmount(paymentAmount);
aliPaytl.setChannel("ALI_OFFLINE_QRCODE");
aliPaytl.setTradeDate(new Date());
aliPayTradeLogsDAO.insert(aliPaytl);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public HashMap<String, Object> refundOrderByALIQr(String orderId,
String refund_amount) {
// TODO Auto-generated method stub
HashMap<String, Object> map = new HashMap<String, Object>();
ALIPayTradeLogs ali = aliPayTradeLogsService.selectByOrderId(Integer
.parseInt(orderId));
if (ali != null) {
Order o = null;
try {
o = orderService.getOrderById(Integer.parseInt(orderId));
} catch (Exception e) {
e.printStackTrace();
}
HashMap<String, Object> queryMap = query(ali.getOutTradeNo(),
o.getCompanyId(), o.getSubCompanyId());
int flag = (Integer) queryMap.get("flag");
String tradeNo = (String) queryMap.get("tradeNo");
if (flag == 1) {
boolean refundFlag = refundOrder(tradeNo, refund_amount, "",
o.getCompanyId(), o.getSubCompanyId());
map.put("refundFlag", refundFlag);
map.put("refundMsg", "支付寶掃碼(企業)提示:該支付款按原路退到買家帳號,請注意查收!");
} else if (flag == 2) {
map.put("refundFlag", false);
map.put("refundMsg", "平臺提示:支付寶掃碼等待付款");
} else if (flag == 3) {
map.put("refundFlag", false);
map.put("refundMsg", "平臺提示:支付寶掃碼未付款關閉,或已付款的訂單全額退款後關閉");
} else if (flag == 4) {
map.put("refundFlag", false);
map.put("refundMsg", "平臺提示:支付寶掃碼訂單不可退款或撤銷");
} else if (flag == 0) {
map.put("refundFlag", false);
map.put("refundMsg", "平臺提示:支付寶掃碼請求未成功,請重試");
}
}
return map;
}
public HashMap<String, Object> query(final String out_trade_no,
String companyId, String subCompanyId) {
String tradeNo = "";
HashMap<String, Object> map = new HashMap<String, Object>();
AlipayClient alipayClient = getAlipayClientByCompanyId(companyId,
subCompanyId);
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
String biz_content = "{\"out_trade_no\":\"" + out_trade_no + "\"}";
request.setBizContent(biz_content);
AlipayTradeQueryResponse response = null;
try {
response = alipayClient.execute(request);
System.out.println(response.getBody());
System.out.println(response.getCode());
if (null != response && response.isSuccess()) {
System.out.println("買家賬號:" + response.getBuyerLogonId());
System.out.println("商戶訂單號:" + response.getOutTradeNo());
System.out.println("支付寶交易號:" + response.getTradeNo());
System.out.println("總金額:" + response.getTotalAmount());
System.out.println("訂單狀態:" + response.getTradeStatus());
if (response.getCode().equals("10000")) {
tradeNo = response.getTradeNo();
if ("TRADE_SUCCESS".equalsIgnoreCase(response
.getTradeStatus())) {
map.put("tradeNo", tradeNo);
map.put("flag", 1);
// 表示已付款
} else if ("WAIT_BUYER_PAY".equalsIgnoreCase(response
.getTradeStatus())) {
map.put("tradeNo", tradeNo);
map.put("flag", 2);
// 表示等待付款
} else if ("TRADE_CLOSED".equalsIgnoreCase(response
.getTradeStatus())) {
map.put("tradeNo", tradeNo);
map.put("flag", 3);
// 表示未付款關閉,或已付款的訂單全額退款後關閉
} else if ("TRADE_FINISHED".equalsIgnoreCase(response
.getTradeStatus())) {
// 此狀態,訂單不可退款或撤銷
map.put("tradeNo", tradeNo);
map.put("flag", 4);
}
} else {
// 如果請求未成功,請重試
map.put("tradeNo", tradeNo);
map.put("flag", 0);
}
}
} catch (AlipayApiException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return map;
}
/**
* 申請退單
*
* @param trade_no
* @author jinlong.rhj
* @date 2015年4月27日
* @version 1.0
* @return
*/
public boolean refundOrder(String trade_no, String refund_amount,
String out_request_no, String companyId, String subCompanyId) {
boolean flag = false;
AlipayClient alipayClient = getAlipayClientByCompanyId(companyId,
subCompanyId);
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
String biz_content = "{\"trade_no\":\""
+ trade_no
+ "\",\"refund_amount\":\""
+ refund_amount
+ "\",\"out_request_no\":\""
+ out_request_no
+ "\",\"refund_reason\":\"正常退單\",\"store_id\":\"\",\"terminal_id\":\"\"}";
System.out.println(biz_content);
request.setBizContent(biz_content);
AlipayTradeRefundResponse response = null;
try {
response = alipayClient.execute(request);
// System.out.println(response.getBody());
// System.out.println(response.getCode());
// System.out.println(response.getMsg());
// System.out.println(response.getSubCode());
// System.out.println(response.getSubMsg());
// System.out.println(response.getBuyerLogonId());
// System.out.println(response.getFundChange());
// System.out.println(response.getOpenId());
// System.out.println(response.getOutTradeNo());
// System.out.println(response.getRefundFee());
// System.out.println(response.getGmtRefundPay());
// System.out.println(response.getOpenId());
if (null != response && response.isSuccess()) {
if (response.getCode().equals("10000")) {
if (response.getFundChange().equals("Y")) {
// 退款成功,資金有變動,做業務及賬務處理
flag = true;
} else {
// 資金無變動,不必做賬務處理
}
} else {
// 沒有撤銷成功,需要重試幾次
// refundOrderRetry(trade_no, refund_amount, out_request_no,
// 6);
}
}
} catch (AlipayApiException e) {
e.printStackTrace();
}
return flag;
}
@Override
public AlipayClient getAlipayClientByCompanyId(String companyId,
String subCompanyId) {
HashMap<String, Object> map2 = new HashMap<String, Object>();
map2.put("companyId", companyId);
map2.put("subCompanyId", subCompanyId);
ALIPayConfigure aliPayConfigure = aliPayConfigureService
.selectAppId(map2);
DefaultAlipayClient alipayClient = null;
if (aliPayConfigure != null) {
alipayClient = new DefaultAlipayClient(
AlipayServiceEnvConstants.ALIPAY_GATEWAY,
aliPayConfigure.getAppId(),
aliPayConfigure.getPrivateKey(), "json",
AlipayServiceEnvConstants.CHARSET,
AlipayServiceEnvConstants.ALIPAY_PUBLIC_KEY);
}
return alipayClient;
}
/**
* 支付寶掃碼支付二維碼生成介面
*
* @param out_trade_no
* @param total_amount
* @param subject
* @param companyId
* @return
*/
public AlipayTradePrecreateResponse qrPay(String out_trade_no,
String total_amount, String subject, String companyId,
String orderId, String subCompanyId) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time_expire = sdf.format(System.currentTimeMillis() + 24 * 60
* 60 * 1000);
StringBuilder sb = new StringBuilder();
sb.append("{\"out_trade_no\":\"" + out_trade_no + "\",");
sb.append("\"total_amount\":\"" + total_amount
+ "\",\"discountable_amount\":\"0.00\",");
sb.append("\"subject\":\"" + subject + "\",");
sb.append("\"time_expire\":\"" + time_expire + "\"}");
System.out.println(sb.toString());
AlipayClient alipayClient = getAlipayClientByCompanyId(companyId,
subCompanyId);
// 使用SDK,構建群發請求模型
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
request.setBizContent(sb.toString());
request.setNotifyUrl(ConfigUtil.SYS_BASE_URL
+ "/aliPay!notifyMsgByAliPay.action" + "?orderId=" + orderId
+ "&totalAmount=" + total_amount + "&outTradeNo="
+ out_trade_no);
AlipayTradePrecreateResponse response = null;
// 商家配置不成功
if (alipayClient == null) {
return response;
}
try {
// 使用SDK,呼叫交易下單介面
response = alipayClient.execute(request);
System.out.println(response.getBody());
System.out.println(response.isSuccess());
System.out.println(response.getMsg());
// 這裡只是簡單的列印,請開發者根據實際情況自行進行處理
if (null != response && response.isSuccess()) {
if (response.getCode().equals("10000")) {
System.out.println("商戶訂單號:" + response.getOutTradeNo());
System.out.println("二維碼值:" + response.getQrCode());// 商戶將此二維碼值生成二維碼,然後展示給使用者,使用者用支付寶手機錢包掃碼完成支付
// 二維碼的生成,網上有許多開源方法,可以參看:http://blog.csdn.net/feiyu84/article/details/9089497
} else {
// 列印錯誤碼
System.out.println("錯誤碼:" + response.getSubCode());
System.out.println("錯誤描述:" + response.getSubMsg());
}
}
} catch (AlipayApiException e) {
}
return response;
}
}
ALIPayService介面
import java.util.HashMap;
import com.alipay.api.AlipayClient;
import com.alipay.api.response.AlipayTradePrecreateResponse;
public interface ALIPayService {
/**
* 支付寶掃碼支付成功後,訂單業務處理
*
* @param orderId
*/
public void aliPayFinsh(Integer orderId, String totalAmount,
String outTradeNo);
/**
* 支付寶掃碼支付申請退款業務處理
*
* @param orderId
* @param refund_amount
* @return
*/
public HashMap<String, Object> refundOrderByALIQr(String orderId, String refund_amount);
/**
* 各商家的獲得API呼叫客戶端
*
* @param companyId
* @param subCompanyId
* @return
*/
public AlipayClient getAlipayClientByCompanyId(String companyId,
String subCompanyId);
/**
* 支付寶掃碼支付二維碼生成介面
*
* @param out_trade_no
* @param total_amount
* @param subject
* @param companyId
* @return
*/
public AlipayTradePrecreateResponse qrPay(String out_trade_no,
String total_amount, String subject, String companyId,
String orderId, String subCompanyId);
}