微信刷卡支付java,微信刷卡支付一天限額多少

本文目錄一覽:

用Java怎麼實現微信支付

具體方法步驟:

一、準備階段:已認證微信號,且通過微信支付認證,這個可以看微信文檔,很詳細,這裡就不再重複。

二、配置授權目錄,官方推薦使用https類型的url,不知道http能不能行,個人也推薦使用https的保證不會錯。

配置授權域名

三、微信支付二次開發所需要的參數:

APP_ID,APP_KEY,PARTNER,PARTNER_KEY(AppSecret)

APP_ID和PARTNER_KEY(AppSecret)

PARTNER

APP_KEY(自行設置32位字符)

四、具體編程

1、通過頁面跳轉到確認支付頁面,其中的redirect_uri必須是配置授權目錄下的。

2、獲取到openid,再經服務器向微信請求獲取prepay_id,封裝字段並進行簽名後通過jsapi調起微信支付

3、測試結果

         

微信支付Java如何判斷回調

微信支付Java判斷回調方法:

微信支付完成支付調用的時候,在傳入的參數中有一個是執行支付完成之後結果回調的參數,這個回調函數就是微信調用這個接口來將支付成功的結果。

微信支付後端篇

微信支付系列文章

微信支付-java後端實現

微信支付-vue 前端實現

java demo: 下載地址文章底部

技術棧

Spring boot

java

XML (微信在http協議中數據傳輸方案)

MD5 簽名

微信支付術語

openid (OpenID是公眾號一對一對應用戶身份的標識)

app_id (公眾號id,登錄微信公眾號–開發–基本配置中獲得;)

key (收款商戶後台進行配置,登錄微信商戶平台–賬戶中心–API安全-設置秘鑰,設置32位key值;)

mch_id (收款商家商戶號;)

certPath (API證書, 登錄微信商戶平台–賬戶中心-API安全-下載證書)

後端流程

服務端需要的核心操作, 總共分為以下幾步:

統一下單

前端調起微信支付必要參數 (需加密)

訂單結果主動通知 (回調接口)

查詢訂單結果

結束訂單支付接口(關閉訂單,支付訂單關閉)

代碼

微信總共支持多種語言的sdk, 在官網可以下載例子, java程序也可以引入微信支付的sdk包, 但是github上的sdk已經很久沒有更新了, 最好的選擇, 也是我的選擇, 在官網上下載sdk項目, 將其中所有java類copy到自己的項目中.

官網sdk下載目錄

鏈接: 商戶平台首頁

#### 根據微信sdk生成配置類 WXPayConfig

創建IWxPayConfig.class, 繼承sdk WXPayConfig.class, 實現sdk中部分抽象方法, 讀取本地證書, 加載到配置類中.

package core.com.chidori.wxpay;

import core.com.wxpay.IWXPayDomain;

import core.com.wxpay.WXPayConfig;

import core.com.wxpay.WXPayConstants;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStream;

@Service

public class IWxPayConfig extends WXPayConfig { // 繼承sdk WXPayConfig 實現sdk中部分抽象方法

private byte[] certData;

@Value(“${vendor.wx.config.app_id}”)

private String app_id;

@Value(“${vendor.wx.pay.key}”)

private String wx_pay_key;

@Value(“${vendor.wx.pay.mch_id}”)

private String wx_pay_mch_id;

public IWxPayConfig() throws Exception { // 構造方法讀取證書, 通過getCertStream 可以使sdk獲取到證書

String certPath = “/data/config/chidori/apiclient_cert.p12”;

File file = new File(certPath);

InputStream certStream = new FileInputStream(file);

this.certData = new byte[(int) file.length()];

certStream.read(this.certData);

certStream.close();

}

@Override

public String getAppID() {

return app_id;

}

@Override

public String getMchID() {

return wx_pay_mch_id;

}

@Override

public String getKey() {

return wx_pay_key;

}

@Override

public InputStream getCertStream() {

return new ByteArrayInputStream(this.certData);

}

@Override

public IWXPayDomain getWXPayDomain() { // 這個方法需要這樣實現, 否則無法正常初始化WXPay

IWXPayDomain iwxPayDomain = new IWXPayDomain() {

@Override

public void report(String domain, long elapsedTimeMillis, Exception ex) {

}

@Override

public DomainInfo getDomain(WXPayConfig config) {

return new IWXPayDomain.DomainInfo(WXPayConstants.DOMAIN_API, true);

}

};

return iwxPayDomain;

}

}

發起統一下單 AND 前端調起微信支付必要參數

// 發起微信支付

WXPay wxpay = null;

Map result = new HashMap();

try {

// ******************************************

//

// 統一下單

//

// ******************************************

wxpay = new WXPay(iWxPayConfig); // *** 注入自己實現的微信配置類, 創建WXPay核心類, WXPay 包括統一下單接口

Map data = new HashMap ();

data.put(“body”, “訂單詳情”);

data.put(“out_trade_no”, transOrder.getGlobalOrderId()); // 訂單唯一編號, 不允許重複

data.put(“total_fee”, String.valueOf(transOrder.getOrderAmount().multiply(new BigDecimal(100)).intValue())); // 訂單金額, 單位分

data.put(“spbill_create_ip”, “192.168.31.166”); // 下單ip

data.put(“openid”, openId); // 微信公眾號統一標示openid

data.put(“notify_url”, “”); // 訂單結果通知, 微信主動回調此接口

data.put(“trade_type”, “JSAPI”); // 固定填寫

logger.info(“發起微信支付下單接口, request={}”, data);

Map response = wxpay.unifiedOrder(data); // 微信sdk集成方法, 統一下單接口unifiedOrder, 此處請求 MD5加密 加密方式

logger.info(“微信支付下單成功, 返回值 response={}”, response);

String returnCode = response.get(“return_code”);

if (!SUCCESS.equals(returnCode)) {

return null;

}

String resultCode = response.get(“result_code”);

if (!SUCCESS.equals(resultCode)) {

return null;

}

String prepay_id = response.get(“prepay_id”);

if (prepay_id == null) {

return null;

}

// ******************************************

//

// 前端調起微信支付必要參數

//

// ******************************************

String packages = “prepay_id=” + prepay_id;

Map wxPayMap = new HashMap ();

wxPayMap.put(“appId”, iWxPayConfig.getAppID());

wxPayMap.put(“timeStamp”, String.valueOf(Utility.getCurrentTimeStamp()));

wxPayMap.put(“nonceStr”, Utility.generateUUID());

wxPayMap.put(“package”, packages);

wxPayMap.put(“signType”, “MD5”);

// 加密串中包括 appId timeStamp nonceStr package signType 5個參數, 通過sdk WXPayUtil類加密, 注意, 此處使用 MD5加密 方式

String sign = WXPayUtil.generateSignature(wxPayMap, iWxPayConfig.getKey());

// ******************************************

//

// 返回給前端調起微信支付的必要參數

//

// ******************************************

result.put(“prepay_id”, prepay_id);

result.put(“sign”, sign);

result.putAll(wxPayMap);

return result;

} catch (Exception e) {

}

回調結果處理

核心是支付訂單回調時, 需校驗加密簽名是否匹配, 防止出現模擬成功通知

@RequestMapping(value = “/payCallback”, method = RequestMethod.POST)

public String payCallback(HttpServletRequest request, HttpServletResponse response) {

logger.info(“進入微信支付異步通知”);

String resXml=””;

try{

//

InputStream is = request.getInputStream();

//將InputStream轉換成String

BufferedReader reader = new BufferedReader(new InputStreamReader(is));

StringBuilder sb = new StringBuilder();

String line = null;

try {

while ((line = reader.readLine()) != null) {

sb.append(line + ” “);

}

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

resXml=sb.toString();

logger.info(“微信支付異步通知請求包: {}”, resXml);

return wxTicketService.payBack(resXml);

}catch (Exception e){

logger.error(“微信支付回調通知失敗”,e);

String result = ” “;

return result;

}

}

@Override

public String payBack(String notifyData) {

logger.info(“payBack() start, notifyData={}”, notifyData);

String xmlBack=””;

Map notifyMap = null;

try {

WXPay wxpay = new WXPay(iWxPayConfig);

notifyMap = WXPayUtil.xmlToMap(notifyData); // 轉換成map

if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {

// 簽名正確

// 進行處理。

// 注意特殊情況:訂單已經退款,但收到了支付結果成功的通知,不應把商戶側訂單狀態從退款改成支付成功

String return_code = notifyMap.get(“return_code”);//狀態

String out_trade_no = notifyMap.get(“out_trade_no”);//訂單號

if (out_trade_no == null) {

logger.info(“微信支付回調失敗訂單號: {}”, notifyMap);

xmlBack = ” “;

return xmlBack;

}

// 業務邏輯處理 ****************************

logger.info(“微信支付回調成功訂單號: {}”, notifyMap);

xmlBack = ” “;

return xmlBack;

} else {

logger.error(“微信支付回調通知簽名錯誤”);

xmlBack = ” “;

return xmlBack;

}

} catch (Exception e) {

logger.error(“微信支付回調通知失敗”,e);

xmlBack = ” “;

}

return xmlBack;

}

統一下單的簽名和後續前端拉取微信支付的簽名需要統一, 也就是都採用MD5加密, 如果2者不同, 會導致前端拉取微信支付fail, 這是一個巨大的坑, 因為這個原因調試了好久, 微信在文檔里沒有明確標出統一下單的簽名校驗方式 需要和前端拉取微信支付的簽名校驗保持一致.

微信sdk里的源碼需要針對這個問題調整一下, 調整如下:

WXPay類需要修改下加密判斷,在WXPay構造方法中,調整如下

public WXPay(final WXPayConfig config, final String notifyUrl, final boolean autoReport, final boolean useSandbox) throws Exception {

this.config = config;

this.notifyUrl = notifyUrl;

this.autoReport = autoReport;

this.useSandbox = useSandbox;

if (useSandbox) {

this.signType = SignType.MD5; // 沙箱環境

}

else {

this.signType = SignType.MD5; // 將這裡的加密方式修改為SignType.MD5, 保持跟前端吊起微信加密方式保持一致

}

this.wxPayRequest = new WXPayRequest(config);

}

結束語

做完以後, 微信支付的後端邏輯還是很清晰的, 但是在開發過程中很煎熬, 不清楚每個專業術語在微信哪裡配置, 加密方式亂的很

怎麼用java調用微信支付接口

java調用微信支付接口方法:

RequestHandler requestHandler = new RequestHandler(super.getRequest(),super.getResponse());

//獲取token //兩小時內有效,兩小時後重新獲取

Token = requestHandler.GetToken();

//更新token 到應用中

requestHandler.getTokenReal();

System.out.println(“微信支付獲取token=======================:” +Token);

//requestHandler 初始化

requestHandler.init();

requestHandler.init(appid,appsecret, appkey,partnerkey, key);

// ——————————–本地系統生成訂單————————————-

// 設置package訂單參數

SortedMapString, String packageParams = new TreeMapString, String();

packageParams.put(“bank_type”, “WX”); // 支付類型

packageParams.put(“body”, “xxxx”); // 商品描述

packageParams.put(“fee_type”, “1”); // 銀行幣種

packageParams.put(“input_charset”, “UTF-8”); // 字符集

packageParams.put(“notify_url”, “”); // 通知地址 這裡的通知地址使用外網地址測試,注意80端口是否打開。

packageParams.put(“out_trade_no”, no); // 商戶訂單號

packageParams.put(“partner”, partenerid); // 設置商戶號

packageParams.put(“spbill_create_ip”, super.getRequest().getRemoteHost()); // 訂單生成的機器IP,指用戶瀏覽器端IP

packageParams.put(“total_fee”, String.valueOf(rstotal)); // 商品總金額,以分為單位

// 設置支付參數

SortedMapString, String signParams = new TreeMapString, String();

signParams.put(“appid”, appid);

signParams.put(“noncestr”, noncestr);

signParams.put(“traceid”, PropertiesUtils.getOrderNO());

signParams.put(“timestamp”, timestamp);

signParams.put(“package”, packageValue);

signParams.put(“appkey”, this.appkey);

// 生成支付簽名,要採用URLENCODER的原始值進行SHA1算法!

String sign =””;

try {

sign = Sha1Util.createSHA1Sign(signParams);

} catch (Exception e) {

e.printStackTrace();

}

// 增加非參與簽名的額外參數

signParams.put(“sign_method”, “sha1”);

signParams.put(“app_signature”, sign);

// api支付拼包結束————————————

//獲取prepayid

String prepayid = requestHandler.sendPrepay(signParams);

System.out.println(“prepayid :” + prepayid);

// ——————————–生成完成———————————————

//生成預付快訂單完成,返回給android,ios 掉起微信所需要的參數。

SortedMapString, String payParams = new TreeMapString, String();

payParams.put(“appid”, appid);

payParams.put(“noncestr”, noncestr);

payParams.put(“package”, “Sign=WXPay”);

payParams.put(“partnerid”, partenerid);

payParams.put(“prepayid”, prepayid);

payParams.put(“appkey”, this.appkey);

//這裡除1000 是因為參數長度限制。

int time = (int) (System.currentTimeMillis() / 1000);

payParams.put(“timestamp”,String.valueOf(time));

System.out.println(“timestamp:” + time);

//簽名

String paysign =””;

try {

paysign = Sha1Util.createSHA1Sign(payParams);

} catch (Exception e) {

e.printStackTrace();

}

payParams.put(“sign”, paysign);

//拼json 數據返回給客戶端

BasicDBObject backObject = new BasicDBObject();

backObject.put(“appid”, appid);

backObject.put(“noncestr”, payParams.get(“noncestr”));

backObject.put(“package”, “Sign=WXPay”);

backObject.put(“partnerid”, payParams.get(“partnerid”));

backObject.put(“prepayid”, payParams.get(“prepayid”));

backObject.put(“appkey”, this.appkey);

backObject.put(“timestamp”,payParams.get(“timestamp”));

backObject.put(“sign”,payParams.get(“sign”));

String backstr = dataObject.toString();

System.out.println(“backstr:” + backstr);

return backstr;

====================到此為止,預付款訂單已生成,並且已返回客戶端====================

//坐等微信服務器通知,通知的地址就是生成預付款訂單的notify_url

ResponseHandler resHandler = new ResponseHandler(request, response);

resHandler.setKey(partnerkey);

//創建請求對象

//RequestHandler queryReq = new RequestHandler(request, response);

//queryReq.init();

if (resHandler.isTenpaySign() == true) {

//商戶訂單號

String out_trade_no = resHandler.getParameter(“out_trade_no”);

System.out.println(“out_trade_no:” + out_trade_no);

//財付通訂單號

String transaction_id = resHandler.getParameter(“transaction_id”);

System.out.println(“transaction_id:” + transaction_id);

//金額,以分為單位

String total_fee = resHandler.getParameter(“total_fee”);

//如果有使用折扣券,discount有值,total_fee+discount=原請求的total_fee

String discount = resHandler.getParameter(“discount”);

//支付結果

String trade_state = resHandler.getParameter(“trade_state”);

//判斷簽名及結果

if (“0”.equals(trade_state)) {

//——————————

//即時到賬處理業務開始

//——————————

System.out.println(“—————-業務邏輯執行—————–“);

//——請根據您的業務邏輯來編寫程序(以上代碼僅作參考)——

System.out.println(“—————-業務邏輯執行完畢—————–“);

System.out.println(“success”); // 請不要修改或刪除

System.out.println(“即時到賬支付成功”);

//給財付通系統發送成功信息,財付通系統收到此結果後不再進行後續通知

resHandler.sendToCFT(“success”);

//給微信服務器返回success 否則30分鐘通知8次

return “success”;

}else{

System.out.println(“通知簽名驗證失敗”);

resHandler.sendToCFT(“fail”);

response.setCharacterEncoding(“utf-8”);

}

}else {

System.out.println(“fail -Md5 failed”);

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/246433.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 13:15
下一篇 2024-12-12 13:15

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java Bean加載過程

    Java Bean加載過程涉及到類加載器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean加載的過程。 一、類加載器 類加載器是Java虛擬機…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字符串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字符串中是否存在多個指定字符: 一、字符串遍歷 字符串是Java編程中非常重要的一種數據類型。要判斷字符串中是否存在多個指定字符…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29
  • Java 8 Group By 會影響排序嗎?

    是的,Java 8中的Group By會對排序產生影響。本文將從多個方面探討Group By對排序的影響。 一、Group By的概述 Group By是SQL中的一種常見操作,它…

    編程 2025-04-29

發表回復

登錄後才能評論