java實現掃碼槍-微信支付

一品堂.技术学习笔记發表於2024-10-08

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");

相關文章