java实现扫码枪-微信支付
版权
简介: java实现扫码枪-微信支付
实现 Java 扫码枪支付的微信支付功能涉及几个步骤,包括获取微信支付 API 凭证、生成支付二维码、扫描二维码并获取支付结果。以下是一个完整的实现示例,包括详细的注释。
步骤 1:准备工作
确保你已经注册了微信支付账号,并获得了以下信息:
- 商户号(mch_id)
- 应用ID(app_id)
- API 密钥(api_key)
步骤 2:添加依赖
在你的项目中添加必要的依赖。例如,如果你使用的是 Maven
项目,可以在 pom.xml
文件中添加以下依赖:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.3</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
步骤 3:生成微信支付二维码
以下代码示例演示如何生成微信支付二维码:
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
public class WeChatPayQRCode {
private static final String WECHAT_PAY_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
private static final String APP_ID = "your_app_id";
private static final String MCH_ID = "your_mch_id";
private static final String API_KEY = "your_api_key";
private static final String NOTIFY_URL = "http://your_notify_url";
private static final String TRADE_TYPE = "NATIVE";
public static void main(String[] args) throws Exception {
String productId = UUID.randomUUID().toString().replaceAll("-", "");
String qrCodeUrl = generateWeChatQRCode("Test Product", productId, 1);
System.out.println("QR Code URL: " + qrCodeUrl);
}
public static String generateWeChatQRCode(String productDescription, String productId, int totalFee) throws Exception {
SortedMap<String, String> params = new TreeMap<>();
params.put("appid", APP_ID);
params.put("mch_id", MCH_ID);
params.put("nonce_str", UUID.randomUUID().toString().replaceAll("-", ""));
params.put("body", productDescription);
params.put("out_trade_no", productId);
params.put("total_fee", String.valueOf(totalFee));
params.put("spbill_create_ip", "127.0.0.1");
params.put("notify_url", NOTIFY_URL);
params.put("trade_type", TRADE_TYPE);
String sign = generateSignature(params, API_KEY);
params.put("sign", sign);
String xmlRequest = mapToXml(params);
String responseXml = sendPost(WECHAT_PAY_URL, xmlRequest);
Map<String, String> responseMap = xmlToMap(responseXml);
if ("SUCCESS".equals(responseMap.get("return_code")) && "SUCCESS".equals(responseMap.get("result_code"))) {
return responseMap.get("code_url");
} else {
throw new RuntimeException("Failed to generate WeChat QR Code: " + responseMap.get("return_msg"));
}
}
private static String generateSignature(SortedMap<String, String> params, String apiKey) throws Exception {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (entry.getValue() != null && !"".equals(entry.getValue()) && !"sign".equals(entry.getKey())) {
sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
}
sb.append("key=").append(apiKey);
return org.apache.commons.codec.digest.DigestUtils.md5Hex(sb.toString()).toUpperCase();
}
private static String mapToXml(SortedMap<String, String> params) {
StringBuilder sb = new StringBuilder();
sb.append("<xml>");
for (Map.Entry<String, String> entry : params.entrySet()) {
sb.append("<").append(entry.getKey()).append(">").append(entry.getValue()).append("</").append(entry.getKey()).append(">");
}
sb.append("</xml>");
return sb.toString();
}
private static String sendPost(String url, String xml) throws Exception {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(xml, "UTF-8"));
CloseableHttpResponse response = httpClient.execute(httpPost);
try {
return EntityUtils.toString(response.getEntity(), "UTF-8");
} finally {
response.close();
httpClient.close();
}
}
private static Map<String, String> xmlToMap(String xml) throws Exception {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(xml, HashMap.class);
}
}
步骤 4:处理扫码枪输入
扫码枪通常作为键盘输入设备工作,因此可以直接读取输入内容。
import java.util.Scanner;
public class ScannerInput {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请扫描二维码:");
while (scanner.hasNextLine()) {
String input = scanner.nextLine();
System.out.println("扫码内容: " + input);
// 在这里调用支付查询接口,检查支付状态
// checkPaymentStatus(input);
}
}
}
步骤 5:查询支付状态
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
public class WeChatPayQuery {
private static final String WECHAT_PAY_QUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
private static final String APP_ID = "your_app_id";
private static final String MCH_ID = "your_mch_id";
private static final String API_KEY = "your_api_key";
public static void main(String[] args) throws Exception {
String orderId = "your_order_id";
String result = checkPaymentStatus(orderId);
System.out.println("支付结果: " + result);
}
public static String checkPaymentStatus(String orderId) throws Exception {
SortedMap<String, String> params = new TreeMap<>();
params.put("appid", APP_ID);
params.put("mch_id", MCH_ID);
params.put("nonce_str", UUID.randomUUID().toString().replaceAll("-", ""));
params.put("out_trade_no", orderId);
String sign = generateSignature(params, API_KEY);
params.put("sign", sign);
String xmlRequest = mapToXml(params);
String responseXml = sendPost(WECHAT_PAY_QUERY_URL, xmlRequest);
Map<String, String> responseMap = xmlToMap(responseXml);
if ("SUCCESS".equals(responseMap.get("return_code")) && "SUCCESS".equals(responseMap.get("result_code"))) {
return responseMap.get("trade_state");
} else {
throw new RuntimeException("Failed to query WeChat payment status: " + responseMap.get("return_msg"));
}
}
private static String generateSignature(SortedMap<String, String> params, String apiKey) throws Exception {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (entry.getValue() != null && !"".equals(entry.getValue()) && !"sign".equals(entry.getKey())) {
sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
}
sb.append("key=").append(apiKey);
return org.apache.commons.codec.digest.DigestUtils.md5Hex(sb.toString()).toUpperCase();
}
private static String mapToXml(SortedMap<String, String> params) {
StringBuilder sb = new StringBuilder();
sb.append("<xml>");
for (Map.Entry<String, String> entry : params.entrySet()) {
sb.append("<").append(entry.getKey()).append(">").append(entry.getValue()).append("</").append(entry.getKey()).append(">");
}
sb.append("</xml>");
return sb.toString();
}
private static String sendPost(String url, String xml) throws Exception {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(xml, "UTF-8"));
CloseableHttpResponse response = httpClient.execute(httpPost);
try {
return EntityUtils.toString(response.getEntity(), "UTF-8");
为人:谦逊、激情、博学、审问、慎思、明辨、 笃行
学问:纸上得来终觉浅,绝知此事要躬行
为事:工欲善其事,必先利其器。
态度:道阻且长,行则将至;行而不辍,未来可期
.....................................................................
------- 桃之夭夭,灼灼其华。之子于归,宜其室家。 ---------------
------- 桃之夭夭,有蕡其实。之子于归,宜其家室。 ---------------
------- 桃之夭夭,其叶蓁蓁。之子于归,宜其家人。 ---------------
=====================================================================