微信APP支付接入流程(含服務端丈冬,非第三方)

首先是微信APP的支付流程流酬,看著很多流程币厕,其實主要的大致分為以下幾個步驟

1.客戶端選擇商品下單(即要購買的這個物品多少錢,我就向微信支付服務端發(fā)送金額的參數(shù)為多少)

2.微信支付服務端收到你的消息后芽腾,再去調用統(tǒng)一下單的API(這個要看支付的文檔了旦装,一般這個API的地址是不變的)

3.微信支付服務端獲取到預訂單信息時再發(fā)送給微信支付APP端,APP將通過SDK調起支付摊滔。

微信APP支付業(yè)務流程

下面貼下相關參考代碼


微信支付APP客戶端主要代碼

try {

String url = "http://www.xxx.com/?user_id=" + account + "&totalFee=" +? total_fee*100;

byte[] buf = Util.httpGet(url);

if (buf != null && buf.length > 0) {

String content = new String(buf);

Log.e("get server pay params:", content);

JSONObject json = new JSONObject(content);

if (null != json && !json.has("retcode")) {

PayReq req = new PayReq();

req.appId = json.getString("appid");

req.partnerId = json.getString("partnerid");

req.prepayId = json.getString("prepayid");

req.nonceStr = json.getString("noncestr");

req.timeStamp = json.getString("timestamp");

req.packageValue = json.getString("package");

req.sign = json.getString("sign");

req.extData = "app data"; // optional

Toast.makeText(MainActivity.this, "調起支付中...", Toast.LENGTH_SHORT).show();

// 在支付之前阴绢,如果應用沒有注冊到微信,應該先調用IWXMsg.registerApp將應用注冊到微信

api.sendReq(req);

} else {

Log.d("PAY_GET", "返回錯誤" + json.getString("retmsg"));

Toast.makeText(MainActivity.this, "返回錯誤" + json.getString("retmsg"), Toast.LENGTH_SHORT).show();

}

} else {

Log.d("PAY_GET", "服務器請求錯誤");

Toast.makeText(MainActivity.this, "服務器請求錯誤", Toast.LENGTH_SHORT).show();

}

} catch (Exception e) {

Log.e("PAY_GET", "異常:" + e.getMessage());

Toast.makeText(MainActivity.this, "異常:" + e.getMessage(), Toast.LENGTH_SHORT).show();

}

接下來是微信支付服務端


服務端收到客戶端的請求數(shù)據(jù)艰躺,并在統(tǒng)一下單后回應給客戶端


微信服務端進行統(tǒng)一下單

下面貼出主要代碼

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

// TODO Auto-generated method stub

System.err.println(request.getParameter("user_id"));

? ? System.err.println(request.getParameter("totalFee"));

? ? String? user_id = request.getParameter("user_id");

? ? String? totalFee = request.getParameter("totalFee");

? ? String attach = "{\"user_id\":\"" + user_id + "\"}";

? ? ? wxPayService = new WXserviceImpl();

? ? System.err.println(wxPayService);

? ? try {

? ? ? ? ? //請求預支付訂單

? ? ? ? ? ? Map<String, String> result = wxPayService.dounifiedOrder(attach, totalFee);

? ? ? ? ? ? JSONObject map = new JSONObject();

? ? ? ? ? WxMD5Util md5Util = new WxMD5Util();

? ? ? ? ? map.put("appid", result.get("appid"));

? ? ? ? ? map.put("partnerid", result.get("mch_id"));

? ? ? ? ? map.put("prepayid", result.get("prepay_id"));

? ? ? ? ? map.put("package", "Sign=WXPay");

? ? ? ? ? map.put("noncestr", result.get("nonce_str"));

? ? ? ? ? map.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));//單位為秒

? ? ? ? ? String sign = md5Util.getSign(map);

? ? ? ? ? map.put("sign",sign);

? ? ? ? ? map.put("extdata", attach);


? ? ? ? ? response.setCharacterEncoding("utf-8");

? ? ? ? ? response.setContentType("application/json; charset=utf-8");

? ? ? ? ? response.getOutputStream().write(map.toString().getBytes("utf-8"));// 指定編碼為utf-8

} catch (Exception e) {

// TODO: handle exception

System.err.println("異常信息"+e);

}

}



/**

? ? * 調用官方SDK 獲取預支付訂單等參數(shù)

? ? * @param attach 額外參數(shù)

? ? * @param total_fee 總價

? ? * @return

? ? * @throws Exception

? ? */

? ? @Override

? ? public Map<String, String> dounifiedOrder(String attach, String total_fee) throws Exception {

? ? ? ? WxMD5Util md5Util = new WxMD5Util();

? ? ? ? Map<String, String> returnMap = new HashMap<>();

? ? ? ? WXConfigUtil config = new WXConfigUtil();

? ? ? ? System.err.println("使用官方API請求預付訂單");

? ? ? ? WXPay wxpay = new WXPay(config);

? ? ? ? Map<String, String> data = new HashMap<>();

? ? ? ? //生成商戶訂單號呻袭,不可重復

? ? ? ? String out_trade_no = "wxpay" + System.currentTimeMillis();

? ? ? ? data.put("appid", config.getAppID());

? ? ? ? data.put("mch_id", config.getMchID());

? ? ? ? data.put("nonce_str", WXPayUtil.generateNonceStr());

? ? ? ? String body = "訂單支付";

? ? ? ? data.put("body", body);

? ? ? ? data.put("out_trade_no", out_trade_no);

? ? ? ? data.put("total_fee", total_fee);

? ? ? ? //自己的服務器IP地址

? ? ? ? data.put("spbill_create_ip", SPBILL_CREATE_IP);

? ? ? ? //異步通知地址(請注意必須是外網(wǎng))

? ? ? ? data.put("notify_url", NOTIFY_URL);

? ? ? ? //交易類型

? ? ? ? data.put("trade_type", TRADE_TYPE_APP);

? ? ? ? //附加數(shù)據(jù),在查詢API和支付通知中原樣返回腺兴,該字段主要用于商戶攜帶訂單的自定義數(shù)據(jù)

? ? ? ? data.put("attach", attach);

? ? ? ? String sign1 = md5Util.getSign(data);

? ? ? ? data.put("sign", sign1);

? ? ? ? System.err.println("使用官方API請求預付訂單");

? ? ? ? try {


? ? ? ? ? ? //使用官方API請求預付訂單

? ? ? ? ? ? Map<String, String> response = wxpay.unifiedOrder(data);

? ? ? ? ? ? System.out.println(response);

? ? ? ? ? ? String returnCode = response.get("return_code");? ? //獲取返回碼

? ? ? ? ? ? //若返回碼為SUCCESS左电,則會返回一個result_code,再對該result_code進行判斷

? ? ? ? ? ? if (returnCode.equals("SUCCESS")) {//主要返回以下5個參數(shù)

? ? ? ? ? ? ? ? String resultCode = response.get("result_code");

? ? ? ? ? ? ? ? returnMap.put("appid", response.get("appid"));

? ? ? ? ? ? ? ? returnMap.put("mch_id", response.get("mch_id"));

? ? ? ? ? ? ? ? returnMap.put("nonce_str", response.get("nonce_str"));

? ? ? ? ? ? ? ? returnMap.put("sign", response.get("sign"));

? ? ? ? ? ? ? ? if ("SUCCESS".equals(resultCode)) {//resultCode 為SUCCESS,才會返回prepay_id和trade_type

? ? ? ? ? ? ? ? ? ? //獲取預支付交易回話標志

? ? ? ? ? ? ? ? ? ? returnMap.put("trade_type", response.get("trade_type"));

? ? ? ? ? ? ? ? ? ? returnMap.put("prepay_id", response.get("prepay_id"));

? ? ? ? ? ? ? ? ? ? return returnMap;

? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? //此時返回沒有預付訂單的數(shù)據(jù)

? ? ? ? ? ? ? ? ? ? return returnMap;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? return returnMap;

? ? ? ? ? ? }

? ? ? ? } catch (Exception e) {

? ? ? ? ? ? System.out.println(e);

? ? ? ? ? ? //系統(tǒng)等其他錯誤的時候

? ? ? ? }

? ? ? ? return returnMap;

? ? }


需要注意的是微信支付服務端需要APPID页响,商戶號篓足,商戶秘鑰以及從微信商戶平臺下載的安全證書(確保支付安全),對于支付成功的回調闰蚕,查詢訂單和退訂單栈拖,,這里就不再一一貼出了没陡,有問題的可以留言或私信交流涩哟,一篇拙文,還望各位多多擔待盼玄。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末贴彼,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子强岸,更是在濱河造成了極大的恐慌,老刑警劉巖砾赔,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝌箍,死亡現(xiàn)場離奇詭異青灼,居然都是意外死亡,警方通過查閱死者的電腦和手機妓盲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門杂拨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人悯衬,你說我怎么就攤上這事弹沽。” “怎么了筋粗?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵策橘,是天一觀的道長。 經(jīng)常有香客問我娜亿,道長丽已,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任买决,我火速辦了婚禮沛婴,結果婚禮上,老公的妹妹穿的比我還像新娘督赤。我一直安慰自己嘁灯,他們只是感情好,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布躲舌。 她就那樣靜靜地躺著丑婿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪孽糖。 梳的紋絲不亂的頭發(fā)上枯冈,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音办悟,去河邊找鬼尘奏。 笑死,一個胖子當著我的面吹牛病蛉,可吹牛的內容都是我干的炫加。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼铺然,長吁一口氣:“原來是場噩夢啊……” “哼俗孝!你這毒婦竟也來了?” 一聲冷哼從身側響起魄健,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤赋铝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后沽瘦,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體革骨,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡农尖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了良哲。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盛卡。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖筑凫,靈堂內的尸體忽然破棺而出滑沧,到底是詐尸還是另有隱情,我是刑警寧澤巍实,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布滓技,位于F島的核電站,受9級特大地震影響蔫浆,放射性物質發(fā)生泄漏殖属。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一瓦盛、第九天 我趴在偏房一處隱蔽的房頂上張望洗显。 院中可真熱鬧,春花似錦原环、人聲如沸挠唆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玄组。三九已至,卻和暖如春谒麦,著一層夾襖步出監(jiān)牢的瞬間俄讹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工绕德, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留患膛,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓耻蛇,卻偏偏與公主長得像踪蹬,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子臣咖,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355