網址:https://pay.weixin.qq.com/guide/index.shtmlhtml
DEMO下載:https://pay.weixin.qq.com/wiki/doc/api/download/WxPayAPI_JAVA_v3.zipjava
微信支付 Java SDKgit
------github
對[微信支付開發者文檔](https://pay.weixin.qq.com/wiki/doc/api/index.html)中給出的API進行了封裝。算法
com.github.wxpay.sdk.WXPay類下提供了對應的方法:json
|--------|--------|api
|microPay| 刷卡支付 |微信
|unifiedOrder | 統一下單|app
|orderQuery | 查詢訂單 |異步
|reverse | 撤銷訂單 |
|closeOrder|關閉訂單|
|refund|申請退款|
|refundQuery|查詢退款|
|downloadBill|下載對帳單|
|report|交易保障|
|shortUrl|轉換短連接|
|authCodeToOpenid|受權碼查詢openid|
* 參數爲`Map<String, String>`對象,返回類型也是`Map<String, String>`。
* 方法內部會將參數會轉換成含有`appid`、`mch_id`、`nonce_str`、`sign\_type`和`sign`的XML;
* 默認使用MD5進行簽名;
* 經過HTTPS請求獲得返回數據後會對其作必要的處理(例如驗證簽名,簽名錯誤則拋出異常)。
* 對於downloadBill,不管是否成功都返回Map,且都含有`return_code`和`return_msg`。若成功,其中`return_code`爲`SUCCESS`,另外`data`對應對帳單數據。
## 安裝
```
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
```
## 示例
配置類MyConfig:
```java
import com.github.wxpay.sdk.WXPayConfig;
import java.io.*;
public class MyConfig implements WXPayConfig{
private byte[] certData;
public MyConfig() throws Exception {
String certPath = "/path/to/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();
}
public String getAppID() {
return "wx8888888888888888";
}
public String getMchID() {
return "12888888";
}
public String getKey() {
return "88888888888888888888888888888888";
}
public InputStream getCertStream() {
ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
return certBis;
}
public int getHttpConnectTimeoutMs() {
return 8000;
}
public int getHttpReadTimeoutMs() {
return 10000;
}
}
```
```java
import com.github.wxpay.sdk.WXPay;
import java.util.HashMap;
import java.util.Map;
public class WXPayExample {
public static void main(String[] args) throws Exception {
MyConfig config = new MyConfig();
WXPay wxpay = new WXPay(config);
Map<String, String> data = new HashMap<String, String>();
data.put("body", "騰訊充值中心-QQ會員充值");
data.put("out_trade_no", "2016090910595900000012");
data.put("device_info", "");
data.put("fee_type", "CNY");
data.put("total_fee", "1");
data.put("spbill_create_ip", "123.12.12.123");
data.put("notify_url", "http://www.example.com/wxpay/notify");
data.put("trade_type", "NATIVE"); // 此處指定爲掃碼支付
data.put("product_id", "12");
try {
Map<String, String> resp = wxpay.unifiedOrder(data);
System.out.println(resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
```java
import com.github.wxpay.sdk.WXPay;
import java.util.HashMap;
import java.util.Map;
public class WXPayExample {
public static void main(String[] args) throws Exception {
MyConfig config = new MyConfig();
WXPay wxpay = new WXPay(config);
Map<String, String> data = new HashMap<String, String>();
data.put("out_trade_no", "2016090910595900000012");
try {
Map<String, String> resp = wxpay.orderQuery(data);
System.out.println(resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
```java
import com.github.wxpay.sdk.WXPay;
import java.util.HashMap;
import java.util.Map;
public class WXPayExample {
public static void main(String[] args) throws Exception {
MyConfig config = new MyConfig();
WXPay wxpay = new WXPay(config);
Map<String, String> data = new HashMap<String, String>();
data.put("out_trade_no", "2016090910595900000012");
try {
Map<String, String> resp = wxpay.refundQuery(data);
System.out.println(resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
```java
import com.github.wxpay.sdk.WXPay;
import java.util.HashMap;
import java.util.Map;
public class WXPayExample {
public static void main(String[] args) throws Exception {
MyConfig config = new MyConfig();
WXPay wxpay = new WXPay(config);
Map<String, String> data = new HashMap<String, String>();
data.put("bill_date", "20140603");
data.put("bill_type", "ALL");
try {
Map<String, String> resp = wxpay.downloadBill(data);
System.out.println(resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
其餘API的使用和上面相似。
```java
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import java.util.HashMap;
import java.util.Map;
public class WXPayExample {
public static void main(String[] args) throws Exception {
MyConfig config = new MyConfig();
WXPay wxpay = new WXPay(config);
Map<String, String> data = new HashMap<String, String>();
data.put("bill_date", "20140603");
data.put("bill_type", "ALL");
data.put("tar_type", "GZIP");
try {
data = wxpay.fillRequestData(data);
System.out.println(WXPayUtil.mapToXml(data));
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
```java
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import java.util.Map;
public class WXPayExample {
public static void main(String[] args) throws Exception {
String notifyData = "...."; // 支付結果通知的xml格式數據
MyConfig config = new MyConfig();
WXPay wxpay = new WXPay(config);
Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyData); // 轉換成map
if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
// 簽名正確
// 進行處理。
// 注意特殊狀況:訂單已經退款,但收到了支付結果成功的通知,不該把商戶側訂單狀態從退款改爲支付成功
}
else {
// 簽名錯誤,若是數據裏沒有sign字段,也認爲是簽名錯誤
}
}
}
```
HTTPS請求默認使用MD5算法簽名,若須要使用HMAC-SHA256:
```
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
public class WXPayExample {
public static void main(String[] args) throws Exception {
MyConfig config = new MyConfig();
WXPay wxpay = new WXPay(config, WXPayConstants.SignType.HMACSHA256);
// ......
}
}
```
若須要使用sandbox環境:
```
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
public class WXPayExample {
public static void main(String[] args) throws Exception {
MyConfig config = new MyConfig();
WXPay wxpay = new WXPay(config, WXPayConstants.SignType.MD5, true);
// ......
}
}
```
## License
BSD
網站:https://open.alipay.com/developmentAccess/developmentAccess.htm
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.0.52.ALL</version>
</dependency>
//實例化客戶端
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
//實例化具體API對應的request類,類名稱和接口名稱對應,當前調用接口名稱:alipay.trade.app.pay
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//SDK已經封裝掉了公共參數,這裏只須要傳入業務參數。如下方法爲sdk的model入參方式(model和biz_content同時存在的狀況下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody("我是測試數據");
model.setSubject("App支付測試Java");
model.setOutTradeNo(outtradeno);
model.setTimeoutExpress("30m");
model.setTotalAmount("0.01");
model.setProductCode("QUICK_MSECURITY_PAY");
request.setBizModel(model);
request.setNotifyUrl("商戶外網能夠訪問的異步地址");
try {
//這裏和普通的接口調用不一樣,使用的是sdkExecute
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
System.out.println(response.getBody());//就是orderString 能夠直接給客戶端請求,無需再作處理。
} catch (AlipayApiException e) {
e.printStackTrace();
}
//獲取支付寶POST過來反饋信息
Map<String,String> params = new HashMap<String,String>();
Map requestParams = request.getParameterMap();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i]
: valueStr + values[i] + ",";
}
//亂碼解決,這段代碼在出現亂碼時使用。
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
//切記alipaypublickey是支付寶的公鑰,請去open.alipay.com對應應用下查看。
//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
boolean flag = AlipaySignature.rsaCheckV1(params, alipaypublicKey, charset,"RSA2")
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2"); //得到初始化的AlipayClient
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();//建立API對應的request類
request.setBizContent("{" +" \"out_trade_no\":\"20150320010101001\"," +" \"trade_no\":\"2014112611001004680073956707\"" +" }");//設置業務參數
AlipayTradeQueryResponse response = alipayClient.execute(request);//經過alipayClient調用API,得到對應的response類
System.out.print(response.getBody());//根據response中的結果繼續業務邏輯處理
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2"); //得到初始化的AlipayClient AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();//建立API對應的request類 request.setBizContent("{" + " \"out_trade_no\":\"20150320010101001\"," + " \"trade_no\":\"2014112611001004680073956707\"," + " \"out_request_no\":\"1000001\"," + " \"refund_amount\":\"1\"" + " }");//設置業務參數 AlipayTradeRefundResponse response = alipayClient.execute(request);//經過alipayClient調用API,得到對應的response類 System.out.print(response.getBody()); // 根據response中的結果繼續業務邏輯處理
alipay.data.dataservice.bill.downloadurl.query:
爲了保障交易的正確性,支付寶提供了交易帳單數據提供給商戶對帳,對帳說明。
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2"); //得到初始化的AlipayClient
AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest();//建立API對應的request類
request.setBizContent("{" +" \"bill_type\":\"trade\"," +" \"bill_date\":\"2016-04-05\"" +" }");//設置業務參數
AlipayDataDataserviceBillDownloadurlQueryResponse response = alipayClient.execute(request);
System.out.print(response.getBody());//根據response中的結果繼續業務邏輯處理
//將接口返回的對帳單下載地址傳入urlStr
String urlStr = "http://dwbillcenter.alipay.com/downloadBillFile.resource?bizType=X&userId=X&fileType=X&bizDates=X&downloadFileName=X&fileId=X";//指定但願保存的文件路徑
String filePath = "/Users/fund_bill_20160405.csv";
URL url = null;
HttpURLConnection httpUrlConnection = null;
InputStream fis = null;
FileOutputStream fos = null;try {
url = new URL(urlStr);
httpUrlConnection = (HttpURLConnection) url.openConnection();
httpUrlConnection.setConnectTimeout(5 * 1000);
httpUrlConnection.setDoInput(true);
httpUrlConnection.setDoOutput(true);
httpUrlConnection.setUseCaches(false);
httpUrlConnection.setRequestMethod("GET");
httpUrlConnection.setRequestProperty("Charsert", "UTF-8");
httpUrlConnection.connect();
fis = httpUrlConnection.getInputStream();
byte[] temp = new byte[1024];
int b;
fos = new FileOutputStream(new File(filePath));
while ((b = fis.read(temp)) != -1) {
fos.write(temp, 0, b);
fos.flush();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
fos.close();
httpUrlConnection.disconnect();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}