日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

微信APP支付-Android+springboot搭建后端(一)

發布時間:2023/12/20 Android 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 微信APP支付-Android+springboot搭建后端(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這篇教程將詳細的介紹如何實現微信APP支付,分為Android移動端開發和springboot后端開發,有一些在開發過程中遇到的坑將會被標注,解決方案也會給出。

一、準備工作

準備工作就是獲取必要的參數,注冊微信商戶平臺和微信開放平臺分別獲取到商戶號和APPID,并且在微信商戶平臺申請API證書、設置API密鑰、設置APIv3密鑰等



這些工作在公司里會有相關人員做好,將參數給出,直接拿來用即可。準備工作就是比較繁瑣,而且微信開發者認證需要300元。做完相關工作后,一定要查看權限是否申請到,微信商戶平臺是否關聯APPID等。由于這些東西全是我一個人做,所以對流程比較了解。

二、Springboot后端開發

先介紹一下微信支付的后端開發,微信APP支付開發與支付寶支付不一樣,所以在這邊需要將后端搭建好。打開微信支付的文檔中心,我們主要根據官方給的提示按照步驟操作就可以了。這里我們就僅展示APP下單。

1、創建項目

主要的目錄結構如下。包含了配置類,工具類等。包名 com.atguigu.paymentdemo(借鑒了網課)

2、配置文件application.yml和wxpay.properties

application.yml

server:port: 8090 #服務端口spring:application:name: payment-demo #應用的名字jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://ip:3310/payment_demo?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=falseusername: 用戶名password: 密碼mybatis-plus:configuration: #sql日志log-impl: org.apache.ibatis.logging.stdout.StdOutImplmapper-locations: classpath:com/atguigu/paymentdemo/mapper/xml/*.xmllogging:level:root: info

wxpay.properties

# 微信支付相關參數 # 商戶號 wxpay.mch-id=商戶號寫自己的 # 商戶API證書序列號 wxpay.mch-serial-no=寫自己的# 商戶私鑰文件 wxpay.private-key-path=apiclient_key.pem # APIv3密鑰 wxpay.api-v3-key=寫自己的 # API密鑰 wxpay.api-key=寫自己的 # APPID wxpay.appid=寫自己的 # 微信服務器地址 wxpay.domain=https://api.mch.weixin.qq.com # 接收結果通知地址 wxpay.notify-domain=https://ip或者域名

注意:

  • 這里需要注意將上面的參數改為自己申請到的數據(商戶號、序列號、秘鑰等等),逐個修改就可以
  • 這里將申請到的商戶私鑰文件apiclient_key.pem放在了根目錄下
  • 接受回調的通知地址wxpay.notify-domain這里需要注意一下,官方文檔說必須為https地址,所以這里我們就使用一個內網穿透工具生成一個HTTPS地址。請自行查看ngrok這個工具。公司里應該都會給的。

3、配置文件pom.xml

pom.xml

<!--Swagger--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.7.0</version></dependency><!--Swagger ui--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.7.0</version></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--mysql 驅動--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><!--MyBatis-Plus:是MyBatis的增強--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.3.1</version></dependency><!-- 代碼生成器配置 --><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>2.0</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.4.1</version></dependency><!-- 生成自定義配置的元數據信息 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><!--微信支付SDK--><dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId>wechatpay-apache-httpclient</artifactId><version>0.3.0</version></dependency><!--json處理器--><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId></dependency><!--網絡請求--><!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp --><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.9.3</version></dependency>

由于項目打包時會將mapper目錄下xml文件漏掉,所以我們在application.yml文件下配置了classpath:com/atguigu/paymentdemo/mapper/xml/.xml,同時在pom文件下的build下加入下面代碼就可以了,這樣就會在打包時將java目錄中的.xml文件也進行打包。

<build><!-- 項目打包時會將java目錄中的*.xml文件也進行打包 --><resources><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes><filtering>false</filtering></resource></resources></build>

為了讓讀者更好的復現這些功能,下面盡可能的將用到的代碼都放在文章里。

4、vo包

這個目錄主要是生成兩個文件,使用swagger測試時查看響應碼以及收到消息。

ResultCode

public interface ResultCode {public static Integer SUCCESS = 20000;//成功public static Integer ERROR = 20001;//失敗 }

R

@Data @Accessors(chain = true) public class R {@ApiModelProperty(value = "是否成功")private Boolean success;@ApiModelProperty(value = "返回碼")private Integer code;@ApiModelProperty(value = "返回消息")private String message;@ApiModelProperty(value = "返回數據")private Map<String, Object> data = new HashMap<String, Object>();//構造方法私有化private R(){}//鏈式編程//成功靜態方法public static R ok(){R r = new R();r.setSuccess(true);r.setCode(ResultCode.SUCCESS);r.setMessage("成功");return r;}//失敗靜態方法public static R error(){R r = new R();r.setSuccess(false);r.setCode(ResultCode.ERROR);r.setMessage("失敗");return r;}public R success(Boolean success){this.setSuccess(success);return this;}public R message(String message){this.setMessage(message);return this;}public R code(Integer code){this.setCode(code);return this;}public R data(String key, Object value){this.data.put(key, value);return this;}public R data(Map<String, Object> map){this.setData(map);return this;} }

5、config包

這個目錄主要是配置信息,配置Swagger、MyBatisPlus以及WxPay微信支付的參數

Swagger2Config

@Configuration @EnableSwagger2 public class Swagger2Config {@Beanpublic Docket docket(){return new Docket(DocumentationType.SWAGGER_2).apiInfo(new ApiInfoBuilder().title("微信支付案例接口文檔").build());} }

MyBatisPlusConfig

@Configuration @MapperScan("com.atguigu.paymentdemo.mapper") @EnableTransactionManagement //啟用事務管理 public class MyBatisPlusConfig { }

WxPayConfig

這個文件就是讀取到wxpay.properties的信息

@Configuration @PropertySource("classpath:wxpay.properties") //讀取配置文件 @ConfigurationProperties(prefix="wxpay") //讀取wxpay節點 @Data //使用set方法將wxpay節點中的值填充到當前類的屬性中 @Slf4j public class WxPayConfig {// 商戶號private String mchId;// 商戶API證書序列號private String mchSerialNo;// 商戶私鑰文件private String privateKeyPath;// APIv3密鑰private String apiV3Key;// API密鑰private String apiKey;// APPIDprivate String appid;// 微信服務器地址private String domain;// 接收結果通知地址private String notifyDomain;/*** 獲取商戶的私鑰文件* @param filename* @return*/public PrivateKey getPrivateKey(String filename){try {return PemUtil.loadPrivateKey(new FileInputStream(filename));} catch (FileNotFoundException e) {throw new RuntimeException("私鑰文件不存在", e);}}/*** 獲取簽名驗證器* @return*/@Beanpublic ScheduledUpdateCertificatesVerifier getVerifier(){log.info("獲取簽名驗證器");//獲取商戶私鑰PrivateKey privateKey = getPrivateKey(privateKeyPath);//私鑰簽名對象PrivateKeySigner privateKeySigner = new PrivateKeySigner(mchSerialNo, privateKey);//身份認證對象WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner);// 使用定時更新的簽名驗證器,不需要傳入證書ScheduledUpdateCertificatesVerifier verifier = new ScheduledUpdateCertificatesVerifier(wechatPay2Credentials,apiV3Key.getBytes(StandardCharsets.UTF_8));return verifier;}/*** 獲取http請求對象* @param verifier* @return*/@Bean(name = "wxPayClient")public CloseableHttpClient getWxPayClient(ScheduledUpdateCertificatesVerifier verifier){log.info("獲取httpClient");//獲取商戶私鑰PrivateKey privateKey = getPrivateKey(privateKeyPath);WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create().withMerchant(mchId, mchSerialNo, privateKey).withValidator(new WechatPay2Validator(verifier));// ... 接下來,你仍然可以通過builder設置各種參數,來配置你的HttpClient// 通過WechatPayHttpClientBuilder構造的HttpClient,會自動的處理簽名和驗簽,并進行證書自動更新CloseableHttpClient httpClient = builder.build();return httpClient;}/*** 獲取HttpClient,無需進行應答簽名驗證,跳過驗簽的流程*/@Bean(name = "wxPayNoSignClient")public CloseableHttpClient getWxPayNoSignClient(){//獲取商戶私鑰PrivateKey privateKey = getPrivateKey(privateKeyPath);//用于構造HttpClientWechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()//設置商戶信息.withMerchant(mchId, mchSerialNo, privateKey)//無需進行簽名驗證、通過withValidator((response) -> true)實現.withValidator((response) -> true);// 通過WechatPayHttpClientBuilder構造的HttpClient,會自動的處理簽名和驗簽,并進行證書自動更新CloseableHttpClient httpClient = builder.build();log.info("== getWxPayNoSignClient END ==");return httpClient;} }

6、enums包

這個主要是定義微信支付的提供的地址,將其設置為枚舉型,進行拼接就可以組裝成URL地址

WxApiType

@AllArgsConstructor @Getter public enum WxApiType {/*** APP下單*/APP_PAY("/v3/pay/transactions/app"),/*** 類型*/private final String type; }

WxNotifyType

@AllArgsConstructor @Getter public enum WxNotifyType {/*** APP支付通知*/APP_NOTIFY("/api/wx-pay/app/notify"),/*** 類型*/private final String type; }

OrderStatus

@AllArgsConstructor @Getter public enum OrderStatus {/*** 未支付*/NOTPAY("未支付"),/*** 支付成功*/SUCCESS("支付成功"),/*** 已關閉*/CLOSED("超時已關閉"),/*** 已取消*/CANCEL("用戶已取消"),/*** 退款中*/REFUND_PROCESSING("退款中"),/*** 已退款*/REFUND_SUCCESS("已退款"),/*** 退款異常*/REFUND_ABNORMAL("退款異常");/*** 類型*/private final String type; }

PayType

@AllArgsConstructor @Getter public enum PayType {/*** 微信*/WXPAY("微信"),/*** 支付寶*/ALIPAY("支付寶");/*** 類型*/private final String type; }

7、util工具包

HttpClientUtils

/*** http請求客戶端*/ public class HttpClientUtils {private String url;private Map<String, String> param;private int statusCode;private String content;private String xmlParam;private boolean isHttps;public boolean isHttps() {return isHttps;}public void setHttps(boolean isHttps) {this.isHttps = isHttps;}public String getXmlParam() {return xmlParam;}public void setXmlParam(String xmlParam) {this.xmlParam = xmlParam;}public HttpClientUtils(String url, Map<String, String> param) {this.url = url;this.param = param;}public HttpClientUtils(String url) {this.url = url;}public void setParameter(Map<String, String> map) {param = map;}public void addParameter(String key, String value) {if (param == null)param = new HashMap<String, String>();param.put(key, value);}public void post() throws ClientProtocolException, IOException {HttpPost http = new HttpPost(url);setEntity(http);execute(http);}public void put() throws ClientProtocolException, IOException {HttpPut http = new HttpPut(url);setEntity(http);execute(http);}public void get() throws ClientProtocolException, IOException {if (param != null) {StringBuilder url = new StringBuilder(this.url);boolean isFirst = true;for (String key : param.keySet()) {if (isFirst) {url.append("?");isFirst = false;}else {url.append("&");}url.append(key).append("=").append(param.get(key));}this.url = url.toString();}HttpGet http = new HttpGet(url);execute(http);}/*** set http post,put param*/private void setEntity(HttpEntityEnclosingRequestBase http) {if (param != null) {List<NameValuePair> nvps = new LinkedList<NameValuePair>();for (String key : param.keySet())nvps.add(new BasicNameValuePair(key, param.get(key))); // 參數http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 設置參數}if (xmlParam != null) {http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));}}private void execute(HttpUriRequest http) throws ClientProtocolException,IOException {CloseableHttpClient httpClient = null;try {if (isHttps) {SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {// 信任所有public boolean isTrusted(X509Certificate[] chain,String authType)throws CertificateException {return true;}}).build();SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();} else {httpClient = HttpClients.createDefault();}CloseableHttpResponse response = httpClient.execute(http);try {if (response != null) {if (response.getStatusLine() != null)statusCode = response.getStatusLine().getStatusCode();HttpEntity entity = response.getEntity();// 響應內容content = EntityUtils.toString(entity, Consts.UTF_8);}} finally {response.close();}} catch (Exception e) {e.printStackTrace();} finally {httpClient.close();}}public int getStatusCode() {return statusCode;}public String getContent() throws ParseException, IOException {return content;}}

HttpUtils

public class HttpUtils {/*** 將通知參數轉化為字符串* @param request* @return*/public static String readData(HttpServletRequest request) {BufferedReader br = null;try {StringBuilder result = new StringBuilder();br = request.getReader();for (String line; (line = br.readLine()) != null; ) {if (result.length() > 0) {result.append("\n");}result.append(line);}return result.toString();} catch (IOException e) {throw new RuntimeException(e);} finally {if (br != null) {try {br.close();} catch (IOException e) {e.printStackTrace();}}}} }

OrderNoUtils

/*** 訂單號工具類** @author qy* @since 1.0*/ public class OrderNoUtils {/*** 獲取訂單編號* @return*/public static String getOrderNo() {return "ORDER_" + getNo();}/*** 獲取退款單編號* @return*/public static String getRefundNo() {return "REFUND_" + getNo();}/*** 獲取編號* @return*/public static String getNo() {SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");String newDate = sdf.format(new Date());String result = "";Random random = new Random();for (int i = 0; i < 3; i++) {result += random.nextInt(10);}return newDate + result;}}

WechatPay2ValidatorForRequest

/*** @author xy-peng*/ public class WechatPay2ValidatorForRequest {protected static final Logger log = LoggerFactory.getLogger(WechatPay2ValidatorForRequest.class);/*** 應答超時時間,單位為分鐘*/protected static final long RESPONSE_EXPIRED_MINUTES = 5;protected final Verifier verifier;protected final String requestId;protected final String body;public WechatPay2ValidatorForRequest(Verifier verifier, String requestId, String body) {this.verifier = verifier;this.requestId = requestId;this.body = body;}protected static IllegalArgumentException parameterError(String message, Object... args) {message = String.format(message, args);return new IllegalArgumentException("parameter error: " + message);}protected static IllegalArgumentException verifyFail(String message, Object... args) {message = String.format(message, args);return new IllegalArgumentException("signature verify fail: " + message);}public final boolean validate(HttpServletRequest request) throws IOException {try {//處理請求參數validateParameters(request);//構造驗簽名串String message = buildMessage(request);String serial = request.getHeader(WECHAT_PAY_SERIAL);String signature = request.getHeader(WECHAT_PAY_SIGNATURE);//驗簽if (!verifier.verify(serial, message.getBytes(StandardCharsets.UTF_8), signature)) {throw verifyFail("serial=[%s] message=[%s] sign=[%s], request-id=[%s]",serial, message, signature, requestId);}} catch (IllegalArgumentException e) {log.warn(e.getMessage());return false;}return true;}protected final void validateParameters(HttpServletRequest request) {// NOTE: ensure HEADER_WECHAT_PAY_TIMESTAMP at lastString[] headers = {WECHAT_PAY_SERIAL, WECHAT_PAY_SIGNATURE, WECHAT_PAY_NONCE, WECHAT_PAY_TIMESTAMP};String header = null;for (String headerName : headers) {header = request.getHeader(headerName);if (header == null) {throw parameterError("empty [%s], request-id=[%s]", headerName, requestId);}}//判斷請求是否過期String timestampStr = header;try {Instant responseTime = Instant.ofEpochSecond(Long.parseLong(timestampStr));// 拒絕過期請求if (Duration.between(responseTime, Instant.now()).abs().toMinutes() >= RESPONSE_EXPIRED_MINUTES) {throw parameterError("timestamp=[%s] expires, request-id=[%s]", timestampStr, requestId);}} catch (DateTimeException | NumberFormatException e) {throw parameterError("invalid timestamp=[%s], request-id=[%s]", timestampStr, requestId);}}protected final String buildMessage(HttpServletRequest request) throws IOException {String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);String nonce = request.getHeader(WECHAT_PAY_NONCE);return timestamp + "\n"+ nonce + "\n"+ body + "\n";}protected final String getResponseBody(CloseableHttpResponse response) throws IOException {HttpEntity entity = response.getEntity();return (entity != null && entity.isRepeatable()) ? EntityUtils.toString(entity) : "";}}

這上面都是網課里的東西,我直接拿過來用的,都復制過來了。

8、controller包

上面的都是相關的配置文件,終于到重點部分了。在這里我省略了一些東西,Android端發起微信支付的時候,沒有給參數,只展示了這個場景,每個人的需求不一樣,如果需要參數,請自行改動接口,下面代碼我給注釋掉了。

WxPayController

@RestController @RequestMapping("/api/wx-pay") @Api(tags = "微信APP支付APIv3") @Slf4j public class WxPayController {@Resourceprivate WxPayService wxPayService;/*** APP下單* @param* @return* @throws Exception*/@ApiOperation("調用統一下單API,生成APP下單的預支付交易會話標識") // @PostMapping("/native/{productId}")@PostMapping("/native") // public R APPPay(@PathVariable Long productId) throws Exception {public R APPPay() throws Exception {log.info("發起支付請求 v3");//返回支付所需要的參數給Android端Map<String, Object> map = wxPayService.appPay();log.info("map====>{}",map);return R.ok().setData(map);} }

9、service包

WxPayService

public interface WxPayService {/*** app下單* @param* @return*/Map<String, Object> appPay() throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException; }

WxPayServiceImpl

@Service @Slf4j public class WxPayServiceImpl implements WxPayService {@Resourceprivate WxPayConfig wxPayConfig;@Resourceprivate CloseableHttpClient wxPayClient;protected static final SecureRandom RANDOM = new SecureRandom();/*** APP下單* @param* @return*/@Overridepublic Map<String, Object> appPay() throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {log.info("生成訂單");String orderNo = OrderNoUtils.getOrderNo();//生成訂單log.info("調用統一下單API");//調用統一下單APIHttpPost httpPost = new HttpPost(wxPayConfig.getDomain().concat(WxApiType.APP_PAY.getType()));// 請求body參數Gson gson = new Gson();Map paramsMap = new HashMap();paramsMap.put("appid", wxPayConfig.getAppid());paramsMap.put("mchid", wxPayConfig.getMchId());paramsMap.put("description", "whq烤肉");paramsMap.put("out_trade_no", orderNo);paramsMap.put("notify_url", wxPayConfig.getNotifyDomain().concat(WxNotifyType.APP_NOTIFY.getType()));Map amountMap = new HashMap();amountMap.put("total", 1);amountMap.put("currency", "CNY");paramsMap.put("amount", amountMap);//將參數轉換成json字符串String jsonParams = gson.toJson(paramsMap);log.info("請求參數 ===> {}" + jsonParams);StringEntity entity = new StringEntity(jsonParams,"utf-8");entity.setContentType("application/json");httpPost.setEntity(entity);httpPost.setHeader("Accept", "application/json");//完成簽名并執行請求CloseableHttpResponse response = wxPayClient.execute(httpPost);try {String bodyAsString = EntityUtils.toString(response.getEntity());//響應體int statusCode = response.getStatusLine().getStatusCode();//響應狀態碼if (statusCode == 200) { //處理成功log.info("成功, 返回結果 = " + bodyAsString);} else if (statusCode == 204) { //處理成功,無返回Bodylog.info("成功");} else {log.info("APP下單失敗,響應碼 = " + statusCode+ ",返回結果 = " + bodyAsString);throw new IOException("request failed");}//響應結果Map<String, String> resultMap = gson.fromJson(bodyAsString, HashMap.class);//得到返回參數String prepay_id = resultMap.get("prepay_id");Map gettoken = getToken(wxPayConfig.getAppid(),prepay_id);String nonceStr = (String) gettoken.get("nonceStr");String sign = (String) gettoken.get("signature");long timestamp = (long) gettoken.get("timestamp");//返回得到的返回參數Map<String, Object> map = new HashMap<>();map.put("prepayid", prepay_id);map.put("sign", sign);map.put("appid", wxPayConfig.getAppid());map.put("partnerid", wxPayConfig.getMchId());map.put("packagevalue", "Sign=WXPay");map.put("noncestr", nonceStr);map.put("timestamp", timestamp);return map;} finally {response.close();}}/*** 生成字符串* @return*/protected String generateNonceStr() {char[] nonceChars = new char[32];for(int index = 0; index < nonceChars.length; ++index) {nonceChars[index] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".charAt(RANDOM.nextInt("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".length()));}return new String(nonceChars);}/*** 生成簽名值* @param appid* @param prepay_id* @return* @throws IOException* @throws SignatureException* @throws NoSuchAlgorithmException* @throws InvalidKeyException*/Map<String,Object> getToken(String appid,String prepay_id) throws IOException, SignatureException, NoSuchAlgorithmException, InvalidKeyException {//隨機字符串String nonceStr = this.generateNonceStr();//隨機字符串//時間戳long timestamp = System.currentTimeMillis() / 1000;//從下往上依次生成String message = buildMessage(appid, timestamp, nonceStr, prepay_id);//簽名String signature = sign(message.getBytes("utf-8"));Map<String , Object> map = new HashMap<>();map.put("timestamp",timestamp);map.put("nonceStr",nonceStr);map.put("signature",signature);return map;}String sign(byte[] message) throws NoSuchAlgorithmException, SignatureException, IOException, InvalidKeyException {//簽名方式Signature sign = Signature.getInstance("SHA256withRSA");//私鑰,通過MyPrivateKey來獲取,這是個靜態類可以接調用方法 ,需要的是_key.pem文件的絕對路徑配上文件名//獲取商戶私鑰PrivateKey privateKey = wxPayConfig.getPrivateKey(wxPayConfig.getPrivateKeyPath());sign.initSign(privateKey);sign.update(message);return Base64.getEncoder().encodeToString(sign.sign());}/*** 按照前端簽名文檔規范進行排序,\n是換行* @param appid* @param timestamp* @param nonceStr* @param prepay_id* @return*/String buildMessage(String appid, long timestamp,String nonceStr,String prepay_id) {return appid + "\n"+ timestamp + "\n"+ nonceStr + "\n"+ prepay_id + "\n";} }

到這里后端的項目就算完成了,此時運行起來就行了。打開swagger進行測試

返回參數就是這些。我們Android進行接收就完成了!
注意:
以上只是簡單的給出微信APP下單的實現,公司里的需要要更完善,比如保存訂單和訂單狀態,產品等等,這些都要與數據庫交互,所以在上面基礎上繼續完成功能就可以了。

總結

以上是生活随笔為你收集整理的微信APP支付-Android+springboot搭建后端(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。