记录自己的支付集成(微信支付宝)
1. 支付寶
這個支付寶的文檔是個好東西,挺簡單,挺容易看懂的,其次還有沙箱測試,表示支付寶一次通過很開心。 支付沙箱聯調指南
首先導包,這里使用 20170710 的包,提前說明如果使用沙箱需要在支付的activity中添加
EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);
支付的賬號和密碼去沙箱中獲取,支付沙箱聯調指南頁面的最下方,點擊沙箱工具,跳轉過后,頁面左側研發服務-沙箱賬號
這個直接上代碼:ALiPay.java
public class AliPay {// 2017/7/20 沙盒測試通過 代碼無誤//支付寶支付業務:沙箱使用app_idpublic static final String APPID = "2016102200739552";//支付寶支付業務:沙箱使用RSA2_PRIVATEpublic static final String RSA2_PRIVATE = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCTci2x3b/OPT2ESK4+yZpBP7yQxxWdpB2Ht4XL7Vxa+Oa1je3lnnGImtAPsk9Z/LcgrMdg1mrjAP0cHUUHCVs8e70NR1P0YN6zFFDjZ/I4HWYUvAHAB0b/zPCT24xHbekIuyjpvTQKTRPu1QRPyCAlscJjVf6u0aUNh8tTsekxtS5tBOvQ5cm9kHw09XYaO+XtI39ocDj7rzTOkC1uQDfed2YZLXKVbiHm3WNJ71isL9bbC0nkjkBKRDTAGvyDTecvBy/mi8OnVJr9sg270UMNAtgTLONV0eKZp5JSuLwL0PGFXKc07OPb33Na/nsX9qpl6utjETNjJw2AatKMoVEpAgMBAAECggEAZyyXYwX7aHKb8Ev3ecISqaPS7DATJRso+sXl3vv6C0JuFg75sBp98Yv7GXC5bAuVjUy5uz5uzufrNVgZ7EGU0S747CjES5XZX9BQhcA/0xpnSwz/4IJ3IRokIiKX94emcFCe4Whe2PJ0h0QR3033iMjpcB9FtsjGSUCDe85bkkbYbpzTPiv0B5BQlkuSYPR5jR4aeURLJ4qDBiLF+pJHrNy9w0cxPEgKSpY6fusi9fEfs3dKq1a0TbgOMlpHE4ZlOqkjWZld9Z6yU6AYtxfhVzYeYobhPjicmf7cTahfYPYyP4zYfR3PrFOtTCSEOthyzr5TASZeXNMWmyuOb+jnjQKBgQDP4oXSwA7gVMiAk/P7SMRbyn4TEh97CJeWIRWAFJ8r8lCzBuNOMBNbjcsC+3kRdy8rFuFH3yjfKIo2Av/zYT/b441Xm9csVlHH7NLcRD6EYV1DLvgEEc4T+k8jmwRWeri+qzkyY2fH0X8ZdUdMvE271oMViyju5rgQClYMbzVViwKBgQC1kpEsnuXCds7CT89XUqX/nLSqTIfnejm9z/CnR7sPEISI8nQvdokTtyuRm9oV1LZqtN5Zj0Qqo+j3Gvmzgb0pw0sCVAYfmn4+ldicGYNkF1PNgPk8xlLwB395P6Fu8XbyQqlXuTrFVcTz0HWGdkAUuEuhFQgeD9OrqXXCA9BSmwKBgDYe/UQe6ECTEhgXbL+Q9D4Je8UvRK7dT8mwF07fD4l7bnMNagQjFAcT5TSDj8NySf9n14LEoHloroLdSRFt0hhHJ7cVRXGvj18DUuoxgi0oxAUHp1433HTrB8t3QivZi1tobF2n747gBbz1AXkC1SH/+OSU9DUuL+FNL5XRJgt9AoGAKq1kigRfJLIgLvPrXC8E7Wu72ztZxkKoR8EUY30sroHHZRj3ziAiYAvxpavoOrFgnvwcNxjBgPQ90bb5cgPQnnxUqRtuxQbfHX7DBw3IIEKLZAYojuxemiRpBeq62wTOXGrmusPC2JcsT9JzjUNGFJiszhPPcKFvsy2FjDCxSnkCgYEAt+BPODj5cV+aRKvMWdGAapPo/GOVBmQHTtNN/Cw7Lahg9sdunpbAGvyMxfosygnRKV+Ny7VDE4k9wRbm6bIu7esEj5pZv/5fuXU5yCGDNe04GbrUlTbo5Vmw2ChjppMFZSDQDheNn5wiPkTan9Rkx9mZeaHzrZZaKs2vAskKamI=";private static AliPay mAliPay;private Activity mContext;private PayListener mPayListener;private String orderTradeNo;private AliPay(Activity context) {mContext = context;}public static AliPay getInstance(Activity context) {if (mAliPay == null) {synchronized (AliPay.class) {if (mAliPay == null) {mAliPay = new AliPay(context);}}}return mAliPay;}public void startAliPay(final String signOrderInfo, PayListener listener) {mPayListener = listener;Runnable payRunnable = new Runnable() {@Overridepublic void run() {PayTask alipay = new PayTask(mContext);Map<String, String> result = alipay.payV2(signOrderInfo, true);Message msg = new Message();msg.obj = result;mHandler.sendMessage(msg);}};Thread payThread = new Thread(payRunnable);payThread.start();}private Handler mHandler = new Handler(Looper.getMainLooper()) {@SuppressWarnings("unchecked")public void handleMessage(Message msg) {PayResult payResult = new PayResult((Map<String, String>) msg.obj);String resultStatus = payResult.getResultStatus();String resultInfo = payResult.getResult();Log.i("resultinfo", resultInfo);if (mPayListener == null) {return;}// https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.xN1NnL&treeId=204&articleId=105302&docType=1if (payResult == null) {mPayListener.onPayError("結果解析錯誤");return;}if (TextUtils.equals(resultStatus, "9000")) {//支付成功mPayListener.onPaySuccess();} else if (TextUtils.equals(resultStatus, "8000")) {//正在處理中,支付結果未知(有可能已經支付成功),請查詢商戶訂單列表中訂單的支付狀態mPayListener.onPayError("正在處理結果中");} else if (TextUtils.equals(resultStatus, "6001")) {//支付取消mPayListener.onPayCancel();} else if (TextUtils.equals(resultStatus, "6002")) {//網絡連接出錯mPayListener.onPayError("網絡連接出錯");} else if (TextUtils.equals(resultStatus, "4000")) {//支付錯誤mPayListener.onPayError("訂單支付失敗");} else {mPayListener.onPayError(resultInfo);}}};/*** 使用支付寶創建訂單信息* 這個簽名工作要放在后臺服務器中進行處理* 前端將 付訂單參數信息 上傳到服務器 后臺進行簽名處理后,將簽名后的訂單信息發回來** @param itemName* @param itemDescribe* @param itemPrice*/public Map createOrderParamMap(String itemName, String itemDescribe, double itemPrice, String itemTradeNo) {//這里默認使用rsa2私鑰Map<String, String> params = buildOrderParamMap(APPID, itemName, itemDescribe, itemPrice, itemTradeNo, true);return params;}public String createOrderInfo(Map<String, String> params) {return buildOrderParam(params);}/*** 構造支付訂單參數列表** @param app_id* @param itemName 商品名稱* @param itemDecribe 商品詳情* @param itemPrice 商品價格* @param rsa2 是否使用rsa2 建議true;* @return*/private Map<String, String> buildOrderParamMap(String app_id, String itemName, String itemDecribe, double itemPrice, String itemTradeNo, boolean rsa2) {Map<String, String> keyValues = new HashMap<String, String>();keyValues.put("app_id", app_id);keyValues.put("biz_content", "{\"timeout_express\":\"30m\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"total_amount\":\"" + itemPrice + "\",\"subject\":\"" + itemName + "\",\"body\":\"" + itemDecribe + "\",\"out_trade_no\":\"" + itemTradeNo + "\"}");keyValues.put("charset", "utf-8");keyValues.put("method", "alipay.trade.app.pay");keyValues.put("sign_type", rsa2 ? "RSA2" : "RSA");keyValues.put("timestamp", Comm.formatNowTime());keyValues.put("version", "1.0");return keyValues;}/*** 構造支付訂單參數信息** @param map 支付訂單參數* @return*/private String buildOrderParam(Map<String, String> map) {List<String> keys = new ArrayList<String>(map.keySet());StringBuilder sb = new StringBuilder();StringBuilder s = new StringBuilder();for (int i = 0; i < keys.size() - 1; i++) {String key = keys.get(i);String value = map.get(key);sb.append(buildKeyValue(key, value, true));sb.append("&");s.append(key);s.append("=");s.append(value);s.append("&");}String tailKey = keys.get(keys.size() - 1);String tailValue = map.get(tailKey);sb.append(buildKeyValue(tailKey, tailValue, true));s.append(tailKey);s.append("=");s.append(tailValue);Log.i("orderinfo",s.toString());return sb.toString();}/*** 拼接鍵值對** @param key* @param value* @param isEncode* @return*/private static String buildKeyValue(String key, String value, boolean isEncode) {StringBuilder sb = new StringBuilder();sb.append(key);sb.append("=");if (isEncode) {try {sb.append(URLEncoder.encode(value, "UTF-8"));} catch (UnsupportedEncodingException e) {sb.append(value);}} else {sb.append(value);}return sb.toString();}/*** 要求外部訂單號必須唯一。** @return*/public String getOutTradeNo() {SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault());Date date = new Date();String key = format.format(date);Random r = new Random();key = key + r.nextInt();key = key.substring(0, 15);orderTradeNo = key;return key;}/*** 對支付參數信息進行簽名** @param map 待簽名授權信息* @return*/public String getSign(Map<String, String> map) {List<String> keys = new ArrayList<String>(map.keySet());// key排序Collections.sort(keys);StringBuilder authInfo = new StringBuilder();for (int i = 0; i < keys.size() - 1; i++) {String key = keys.get(i);String value = map.get(key);authInfo.append(buildKeyValue(key, value, false));authInfo.append("&");}String tailKey = keys.get(keys.size() - 1);String tailValue = map.get(tailKey);authInfo.append(buildKeyValue(tailKey, tailValue, false));String oriSign = SignUtils.sign(authInfo.toString(), RSA2_PRIVATE, true);String encodedSign = "";try {encodedSign = URLEncoder.encode(oriSign, "UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}return "sign=" + encodedSign;} }然后自定義一個支付結果接口: PayListener
public interface PayListener {//支付成功void onPaySuccess();//支付失敗void onPayError(String resultStatus);//支付取消void onPayCancel(); }然后調用:
注意:
1、這里的signOrderInfo必須要從服務器獲取,我的后臺這里還是給力的,上傳訂單id就把signOrderInfo傳過來了,都不用自己寫,多虧了我的口才。
2、這里的orderInfo是是進行 URLEncoder.encode() 轉碼的(鍵為原文,值進行轉碼),具體內容可以打印出來看下,然后加密sign內容是使用原文(沒有進行轉碼)進行加密
3、這里的Base64.java PayResult.java SignUtils.java 去支付寶的demo中獲取(測試階段)
這里的Base64.java PayResult.java SignUtils.java 去支付寶的demo中獲取(測試階段)
這里的Base64.java PayResult.java SignUtils.java 去支付寶的demo中獲取(測試階段)
這里就是Demo的下載地址了 https://docs.open.alipay.com/54/104509
自己測試的時候可以這么寫:
AliPay aliPay = AliPay.getInstance(this); Map orderParamMap = aliPay.createOrderParamMap("商品名字", "商品描述", 0.01, "123123123123123"); String orderInfo = aliPay.createOrderInfo(orderParamMap); String sign = aliPay.getSign(orderParamMap); String signOrderInfo = orderInfo + "&" + sign;AliPay.getInstance(PayActivity.this).startAliPay(signOrderInfo, new PayListener() {@Overridepublic void onPaySuccess() {Comm.Tip(mContext, "支付成功");}@Overridepublic void onPayError(String resultStatus) {Comm.Tip(mContext, "支付失敗");}@Overridepublic void onPayCancel() {Comm.Tip(mContext, "支付取消");}});2.微信支付
微信支付滿滿的都是坑,特別是官方Demo,看的我頭暈,然后還是沒弄好,很尷尬。
首先注意一個大坑:我們后臺申請接入時候簽名填寫錯誤,我就想說ios沒有簽名,安卓要簽名,然后導致了ios成功,安卓失敗,我找了一下午的原因。
注意:微信開發平臺的申請的應用簽名,如果在手機上安裝debug包獲取的簽名,那么只能debug包才能調用微信支付,如果是release包獲取的簽名,那么只有release包才能調用微信支付,當然,微信開發平臺上的簽名和包名都是可以更換的。
首先導個包,gradle方式也可以,然而我用AS下不下來,只好導包
簡單粗暴上代碼:WechatPay.java
其次是:WXPayEntryActivity .java
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);if (WechatPay.getInstance(this) != null) {WechatPay.getInstance(this).getWXApi().handleIntent(getIntent(), this);} else {finish();}}@Overrideprotected void onNewIntent(Intent intent) {super.onNewIntent(intent);setIntent(intent);if (WechatPay.getInstance(this) != null) {WechatPay.getInstance(this).getWXApi().handleIntent(intent, this);}}@Overridepublic void onReq(BaseReq baseReq) {}@Overridepublic void onResp(BaseResp baseResp) {if (baseResp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {if (WechatPay.getInstance(this) != null) {WechatPay.getInstance(this).onResp(baseResp.errCode, baseResp.errStr);finish();}}} }再來清單文件中:
改下第二行和最后一行的地址
好的,現在開始調用:
我的order類當然也是后臺發給我的嘍
好的,打完收工,完成之后發現,其實也就是那么回事。
總結
以上是生活随笔為你收集整理的记录自己的支付集成(微信支付宝)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 服务器阵列工作原理,服务器RAID技术基
- 下一篇: Java架构师必备技术:java编译器e