Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 日韩综合nv一区二区在线观看,caonila国产在线观看,日本高清无吗

          整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          七爪源碼:使用元掩碼和 javascript 將加密

          七爪源碼:使用元掩碼和 javascript 將加密貨幣支付添加到您的網(wǎng)站

          于如何允許客戶使用他們的 Metamask 錢包進(jìn)行支付的分步指南。

          因此,假設(shè)您有一家在線商店,并希望允許您的客戶使用加密貨幣進(jìn)行購(gòu)買。 在本文中,我們將完成使用 Javascript 和 Metamask 實(shí)現(xiàn)簡(jiǎn)單的加密貨幣支付流程的步驟。

          整個(gè)流程將如下所示:

          支付流程

          執(zhí)行支付的流程如下:

          1. 應(yīng)用程序加載并自動(dòng)檢查 Metamask 錢包是否已連接。 如果沒(méi)有,請(qǐng)顯示連接按鈕。
          2. 如果用戶未連接,他按下連接按鈕并簽署消息以連接到應(yīng)用程序。
          3. 用戶查看并確認(rèn)付款。
          4. 創(chuàng)建一個(gè) Metamask 交易請(qǐng)求,并顯示一個(gè)彈出窗口供用戶確認(rèn)交易。
          5. 用戶確認(rèn)交易,生成一個(gè) Eherscan url,用戶和應(yīng)用程序都收到付款確認(rèn)。


          檢查用戶是否登錄

          首先,當(dāng)頁(yè)面第一次加載時(shí),我們要檢查用戶是否已經(jīng)將錢包連接到應(yīng)用程序。 為此,我們只需使用“eth_accounts”方法獲取用戶的帳戶。 如果未返回任何帳戶,則表示用戶未連接。 這是執(zhí)行此操作的代碼:

          function checkIfWalletConnected() {
              if (window.ethereum.request({ method: 'eth_accounts' }).then(function (accounts) {
                  if (accounts.length > 0) {
                      connected=true;
                      buyerAddress=accounts[0];
                  } else {
                      connected=false;
                  }
              })
              ) {
                  connected=true;
              } else {
                  connected=false;
              }
          }

          如果用戶已登錄,我們會(huì)顯示結(jié)帳菜單,如果沒(méi)有,我們會(huì)顯示一個(gè)連接按鈕。


          將用戶連接到應(yīng)用程序

          如果用戶未連接,我們需要為連接按鈕分配一個(gè)功能,以將錢包連接到應(yīng)用程序。 這可以通過(guò)使用“eth_requestAccounts”方法來(lái)實(shí)現(xiàn)。 此方法將創(chuàng)建一個(gè) Metamask 彈出窗口,供用戶簽署消息并確認(rèn)他想要連接到應(yīng)用程序。

          這是此類功能的代碼:

          function connectWallet() {
              if (window.ethereum) {
                  console.log('MetaMask is installed');
                  window.web3=new Web3(window.ethereum);
                  window.ethereum.send('eth_requestAccounts').then(function() {
                      // Get account address
                      window.ethereum.request({ method: 'eth_accounts' })
                      .then(function(accounts) {
                          if (accounts.length > 0) {
                              buyerAddress=accounts[0];
                          } else {
                              connected=false;
                          }
                      });
          
                  });
              } else if (window.web3) {
                  window.web3=new Web3(window.web3.currentProvider);
                  connected=true;
              } else {
                  connected=false;
              }
          }

          用戶現(xiàn)在將連接到網(wǎng)站并能夠進(jìn)行結(jié)帳。


          處理付款

          對(duì)于最后一部分,我們希望提示用戶通過(guò) Metamask 確認(rèn)交易。 這可以通過(guò)“eth_sendTransaction”方法來(lái)實(shí)現(xiàn):

          function makePaymentRequest(buyerAddress, sellerAddress, itemPriceInWei) {
              // Start wallet payment process
              window.ethereum.request({ method: 'eth_sendTransaction', params: [{ from: buyerAddress, to: sellerAddress, value: itemPriceInWei }] })
              .then(response=> {
                  console.log(response);
                  return true;
              })
              .catch(error=> {
                  console.log(error);
                  return false;
              });
          }


          完整的代碼片段

          此代碼的完整工作版本可以在下面的鏈接中看到。 該片段使用 Vue.js 和 Tailwindcss 來(lái)實(shí)現(xiàn)本文開(kāi)頭所示的接口。


          結(jié)論

          本文是使用 Metamask 快速實(shí)施基本區(qū)塊鏈支付系統(tǒng)的簡(jiǎn)短實(shí)用指南。

          這是最簡(jiǎn)單的實(shí)現(xiàn),但如果您想跟蹤客戶和訂單,不建議這樣做。 如果您有興趣學(xué)習(xí)如何創(chuàng)建一個(gè)更強(qiáng)大的架構(gòu)來(lái)處理訂單跟蹤和更強(qiáng)大的流程,請(qǐng)關(guān)注我,因?yàn)槲覍⒑芸彀l(fā)布一篇關(guān)于我如何使用無(wú)服務(wù)器云功能創(chuàng)建全棧實(shí)現(xiàn)的文章。

          快樂(lè)編碼!

          近公司在做支付模塊,在接入過(guò)程中遇到了很多坑,費(fèi)了不少事,現(xiàn)在分享一下接入方法,也記錄一下,以后可能還用的到。用的是支付寶的即時(shí)到帳支付功能和微信的掃碼支付功能,相比起來(lái),個(gè)人感覺(jué)支付寶的文檔和接入方式都比微信的容易理解和操作,也不用自己寫頁(yè)面,接入起來(lái)比較方便,畢竟是支付起家的,比微信支付少很多坑,下面就分別介紹著兩種支付的接入方法。

          支付寶支付

          1、申請(qǐng)簽約

          目的是得到開(kāi)發(fā)使用的合作伙伴身份(PID)和MD5秘鑰,申請(qǐng)地址(即時(shí)到賬收款):https://b.alipay.com/order/productDetail.htm?productId=2015110218012942


          申請(qǐng)方式在開(kāi)放平臺(tái)的文檔上有詳細(xì)說(shuō)明,這里就不再贅述。

          2、接入支付接口

          在得到PID和秘鑰后就可以接入接口了,首先在開(kāi)放平臺(tái)中下載官方的demo(java+MD5版本),支付寶的demo做的非常好,下載下來(lái)直接配置下jdk就可以運(yùn)行了。如果遇到Java compiler level does not match錯(cuò)誤,說(shuō)明你用的eclipse或myeclipse的jdk編譯版本與demo的JDK編譯版本不一致,修改下jdk編譯版本就可以了。其實(shí)就用到了4個(gè)類,如下圖

          可以選擇把支付功能單獨(dú)做一個(gè)項(xiàng)目,在其他項(xiàng)目調(diào)用接口就可以支付,也可以整合到自己的項(xiàng)目里,為了好維護(hù)我整合到自己的項(xiàng)目里了。把這四個(gè)類放到自己的項(xiàng)目中,引入相應(yīng)的jar包

          2.1、demo中類的說(shuō)明

          AlipayConfig.java類主要是配置參數(shù)信息的類

          package com.fahai.pay.alipay;

          import com.fahai.utils.ProInfoUtil;

          /* *

          *類名:AlipayConfig

          *功能:基礎(chǔ)配置類

          *詳細(xì):設(shè)置帳戶有關(guān)信息及返回路徑

          *版本:3.4

          *修改日期:2016-03-08

          *說(shuō)明:

          *以下代碼只是為了方便商戶測(cè)試而提供的樣例代碼,商戶可以根據(jù)自己網(wǎng)站的需要,按照技術(shù)文檔編寫,并非一定要使用該代碼。

          *該代碼僅供學(xué)習(xí)和研究支付寶接口使用,只是提供一個(gè)參考。

          */

          public class AlipayConfig {

          //↓↓↓↓↓↓↓↓↓↓請(qǐng)?jiān)谶@里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

          // 合作身份者ID,簽約賬號(hào),以2088開(kāi)頭由16位純數(shù)字組成的字符串,查看地址:https://b.alipay.com/order/pidAndKey.htm

          public static String partner="你自己的PID";

          // 收款支付寶賬號(hào),以2088開(kāi)頭由16位純數(shù)字組成的字符串,一般情況下收款賬號(hào)就是簽約賬號(hào)

          public static String seller_id=partner;

          // MD5密鑰,安全檢驗(yàn)碼,由數(shù)字和字母組成的32位字符串,查看地址:https://b.alipay.com/order/pidAndKey.htm

          public static String key="你自己的MD5秘鑰";

          // 服務(wù)器異步通知頁(yè)面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問(wèn)

          //異步通知頁(yè)面,就是接受支付寶支付結(jié)果返回信息的Controller,可以處理自己的支付后的邏輯

          //測(cè)試環(huán)境

          public static String notify_url=ProInfoUtil.getInstance().getProperty("project_url")+"order/pay/aliPayOrder";

          // 頁(yè)面跳轉(zhuǎn)同步通知頁(yè)面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問(wèn)

          //同步跳轉(zhuǎn)的頁(yè)面,就是支付寶支付成功后頁(yè)面跳轉(zhuǎn)的url

          public static String return_url=ProInfoUtil.getInstance().getProperty("project_url")+"order/pay/payResponse";

          // 簽名方式

          public static String sign_type="MD5";

          // 調(diào)試用,創(chuàng)建TXT日志文件夾路徑,見(jiàn)AlipayCore.java類中的logResult(String sWord)打印方法。

          public static String log_path="C:\";

          // 字符編碼格式 目前支持 gbk 或 utf-8

          public static String input_charset="utf-8";

          // 支付類型 ,無(wú)需修改

          public static String payment_type="1";

          // 調(diào)用的接口名,無(wú)需修改

          public static String service="create_direct_pay_by_user";

          //↑↑↑↑↑↑↑↑↑↑請(qǐng)?jiān)谶@里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

          //↓↓↓↓↓↓↓↓↓↓ 請(qǐng)?jiān)谶@里配置防釣魚信息,如果沒(méi)開(kāi)通防釣魚功能,為空即可 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

          // 防釣魚時(shí)間戳 若要使用請(qǐng)調(diào)用類文件submit中的query_timestamp函數(shù)

          public static String anti_phishing_key="";

          // 客戶端的IP地址 非局域網(wǎng)的外網(wǎng)IP地址,如:221.0.0.1

          public static String exter_invoke_ip="";

          //↑↑↑↑↑↑↑↑↑↑請(qǐng)?jiān)谶@里配置防釣魚信息,如果沒(méi)開(kāi)通防釣魚功能,為空即可 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

          }

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60
          • 61

          AlipayCore.java是整理參數(shù)的工具類

          package com.alipay.util;

          import java.io.File;

          import java.io.FileWriter;

          import java.io.IOException;

          import java.util.ArrayList;

          import java.util.Collections;

          import java.util.HashMap;

          import java.util.List;

          import java.util.Map;

          import org.apache.commons.codec.digest.DigestUtils;

          import org.apache.commons.httpclient.methods.multipart.FilePartSource;

          import org.apache.commons.httpclient.methods.multipart.PartSource;

          import com.alipay.config.AlipayConfig;

          /* *

          *類名:AlipayFunction

          *功能:支付寶接口公用函數(shù)類

          *詳細(xì):該類是請(qǐng)求、通知返回兩個(gè)文件所調(diào)用的公用函數(shù)核心處理文件,不需要修改

          *版本:3.3

          *日期:2012-08-14

          *說(shuō)明:

          *以下代碼只是為了方便商戶測(cè)試而提供的樣例代碼,商戶可以根據(jù)自己網(wǎng)站的需要,按照技術(shù)文檔編寫,并非一定要使用該代碼。

          *該代碼僅供學(xué)習(xí)和研究支付寶接口使用,只是提供一個(gè)參考。

          */

          public class AlipayCore {

          /**

          * 除去數(shù)組中的空值和簽名參數(shù)

          * @param sArray 簽名參數(shù)組

          * @return 去掉空值與簽名參數(shù)后的新簽名參數(shù)組

          */

          public static Map<String, String> paraFilter(Map<String, String> sArray) {

          Map<String, String> result=new HashMap<String, String>();

          if (sArray==null || sArray.size() <=0) {

          return result;

          }

          for (String key : sArray.keySet()) {

          String value=sArray.get(key);

          if (value==null || value.equals("") || key.equalsIgnoreCase("sign")

          || key.equalsIgnoreCase("sign_type")) {

          continue;

          }

          result.put(key, value);

          }

          return result;

          }

          /**

          * 把數(shù)組所有元素排序,并按照“參數(shù)=參數(shù)值”的模式用“&”字符拼接成字符串

          * @param params 需要排序并參與字符拼接的參數(shù)組

          * @return 拼接后字符串

          */

          public static String createLinkString(Map<String, String> params) {

          List<String> keys=new ArrayList<String>(params.keySet());

          Collections.sort(keys);

          String prestr="";

          for (int i=0; i < keys.size(); i++) {

          String key=keys.get(i);

          String value=params.get(key);

          if (i==keys.size() - 1) {//拼接時(shí),不包括最后一個(gè)&字符

          prestr=prestr + key + "=" + value;

          } else {

          prestr=prestr + key + "=" + value + "&";

          }

          }

          return prestr;

          }

          /**

          * 寫日志,方便測(cè)試(看網(wǎng)站需求,也可以改成把記錄存入數(shù)據(jù)庫(kù))

          * @param sWord 要寫入日志里的文本內(nèi)容

          */

          public static void logResult(String sWord) {

          FileWriter writer=null;

          try {

          writer=new FileWriter(AlipayConfig.log_path + "alipay_log_" + System.currentTimeMillis()+".txt");

          writer.write(sWord);

          } catch (Exception e) {

          e.printStackTrace();

          } finally {

          if (writer !=null) {

          try {

          writer.close();

          } catch (IOException e) {

          e.printStackTrace();

          }

          }

          }

          }

          /**

          * 生成文件摘要

          * @param strFilePath 文件路徑

          * @param file_digest_type 摘要算法

          * @return 文件摘要結(jié)果

          */

          public static String getAbstract(String strFilePath, String file_digest_type) throws IOException {

          PartSource file=new FilePartSource(new File(strFilePath));

          if(file_digest_type.equals("MD5")){

          return DigestUtils.md5Hex(file.createInputStream());

          }

          else if(file_digest_type.equals("SHA")) {

          return DigestUtils.sha256Hex(file.createInputStream());

          }

          else {

          return "";

          }

          }

          }

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60
          • 61
          • 62
          • 63
          • 64
          • 65
          • 66
          • 67
          • 68
          • 69
          • 70
          • 71
          • 72
          • 73
          • 74
          • 75
          • 76
          • 77
          • 78
          • 79
          • 80
          • 81
          • 82
          • 83
          • 84
          • 85
          • 86
          • 87
          • 88
          • 89
          • 90
          • 91
          • 92
          • 93
          • 94
          • 95
          • 96
          • 97
          • 98
          • 99
          • 100
          • 101
          • 102
          • 103
          • 104
          • 105
          • 106
          • 107
          • 108
          • 109
          • 110
          • 111
          • 112
          • 113
          • 114
          • 115
          • 116
          • 117
          • 118
          • 119
          • 120
          • 121
          • 122

          AlipayNotify.java是驗(yàn)證簽名的類

          package com.alipay.util;

          import java.io.BufferedReader;

          import java.io.InputStreamReader;

          import java.net.HttpURLConnection;

          import java.net.URL;

          import java.util.Map;

          import com.alipay.config.AlipayConfig;

          import com.alipay.sign.MD5;

          /* *

          *類名:AlipayNotify

          *功能:支付寶通知處理類

          *詳細(xì):處理支付寶各接口通知返回

          *版本:3.3

          *日期:2012-08-17

          *說(shuō)明:

          *以下代碼只是為了方便商戶測(cè)試而提供的樣例代碼,商戶可以根據(jù)自己網(wǎng)站的需要,按照技術(shù)文檔編寫,并非一定要使用該代碼。

          *該代碼僅供學(xué)習(xí)和研究支付寶接口使用,只是提供一個(gè)參考

          *************************注意*************************

          *調(diào)試通知返回時(shí),可查看或改寫log日志的寫入TXT里的數(shù)據(jù),來(lái)檢查通知返回是否正常

          */

          public class AlipayNotify {

          /**

          * 支付寶消息驗(yàn)證地址

          */

          private static final String HTTPS_VERIFY_URL="https://mapi.alipay.com/gateway.do?service=notify_verify&";

          /**

          * 驗(yàn)證消息是否是支付寶發(fā)出的合法消息

          * @param params 通知返回來(lái)的參數(shù)數(shù)組

          * @return 驗(yàn)證結(jié)果

          */

          public static boolean verify(Map<String, String> params) {

          //判斷responsetTxt是否為true,isSign是否為true

          //responsetTxt的結(jié)果不是true,與服務(wù)器設(shè)置問(wèn)題、合作身份者ID、notify_id一分鐘失效有關(guān)

          //isSign不是true,與安全校驗(yàn)碼、請(qǐng)求時(shí)的參數(shù)格式(如:帶自定義參數(shù)等)、編碼格式有關(guān)

          String responseTxt="false";

          if(params.get("notify_id") !=null) {

          String notify_id=params.get("notify_id");

          responseTxt=verifyResponse(notify_id);

          }

          String sign="";

          if(params.get("sign") !=null) {sign=params.get("sign");}

          boolean isSign=getSignVeryfy(params, sign);

          //寫日志記錄(若要調(diào)試,請(qǐng)取消下面兩行注釋)

          //String sWord="responseTxt=" + responseTxt + "\n isSign=" + isSign + "\n 返回回來(lái)的參數(shù):" + AlipayCore.createLinkString(params);

          //AlipayCore.logResult(sWord);

          if (isSign && responseTxt.equals("true")) {

          return true;

          } else {

          return false;

          }

          }

          /**

          * 根據(jù)反饋回來(lái)的信息,生成簽名結(jié)果

          * @param Params 通知返回來(lái)的參數(shù)數(shù)組

          * @param sign 比對(duì)的簽名結(jié)果

          * @return 生成的簽名結(jié)果

          */

          private static boolean getSignVeryfy(Map<String, String> Params, String sign) {

          //過(guò)濾空值、sign與sign_type參數(shù)

          Map<String, String> sParaNew=AlipayCore.paraFilter(Params);

          //獲取待簽名字符串

          String preSignStr=AlipayCore.createLinkString(sParaNew);

          //獲得簽名驗(yàn)證結(jié)果

          boolean isSign=false;

          if(AlipayConfig.sign_type.equals("MD5") ) {

          isSign=MD5.verify(preSignStr, sign, AlipayConfig.key, AlipayConfig.input_charset);

          }

          return isSign;

          }

          /**

          * 獲取遠(yuǎn)程服務(wù)器ATN結(jié)果,驗(yàn)證返回URL

          * @param notify_id 通知校驗(yàn)ID

          * @return 服務(wù)器ATN結(jié)果

          * 驗(yàn)證結(jié)果集:

          * invalid命令參數(shù)不對(duì) 出現(xiàn)這個(gè)錯(cuò)誤,請(qǐng)檢測(cè)返回處理中partner和key是否為空

          * true 返回正確信息

          * false 請(qǐng)檢查防火墻或者是服務(wù)器阻止端口問(wèn)題以及驗(yàn)證時(shí)間是否超過(guò)一分鐘

          */

          private static String verifyResponse(String notify_id) {

          //獲取遠(yuǎn)程服務(wù)器ATN結(jié)果,驗(yàn)證是否是支付寶服務(wù)器發(fā)來(lái)的請(qǐng)求

          String partner=AlipayConfig.partner;

          String veryfy_url=HTTPS_VERIFY_URL + "partner=" + partner + "?ify_id=" + notify_id;

          return checkUrl(veryfy_url);

          }

          /**

          * 獲取遠(yuǎn)程服務(wù)器ATN結(jié)果

          * @param urlvalue 指定URL路徑地址

          * @return 服務(wù)器ATN結(jié)果

          * 驗(yàn)證結(jié)果集:

          * invalid命令參數(shù)不對(duì) 出現(xiàn)這個(gè)錯(cuò)誤,請(qǐng)檢測(cè)返回處理中partner和key是否為空

          * true 返回正確信息

          * false 請(qǐng)檢查防火墻或者是服務(wù)器阻止端口問(wèn)題以及驗(yàn)證時(shí)間是否超過(guò)一分鐘

          */

          private static String checkUrl(String urlvalue) {

          String inputLine="";

          try {

          URL url=new URL(urlvalue);

          HttpURLConnection urlConnection=(HttpURLConnection) url.openConnection();

          BufferedReader in=new BufferedReader(new InputStreamReader(urlConnection

          .getInputStream()));

          inputLine=in.readLine().toString();

          } catch (Exception e) {

          e.printStackTrace();

          inputLine="";

          }

          return inputLine;

          }

          }

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60
          • 61
          • 62
          • 63
          • 64
          • 65
          • 66
          • 67
          • 68
          • 69
          • 70
          • 71
          • 72
          • 73
          • 74
          • 75
          • 76
          • 77
          • 78
          • 79
          • 80
          • 81
          • 82
          • 83
          • 84
          • 85
          • 86
          • 87
          • 88
          • 89
          • 90
          • 91
          • 92
          • 93
          • 94
          • 95
          • 96
          • 97
          • 98
          • 99
          • 100
          • 101
          • 102
          • 103
          • 104
          • 105
          • 106
          • 107
          • 108
          • 109
          • 110
          • 111
          • 112
          • 113
          • 114
          • 115
          • 116
          • 117
          • 118
          • 119
          • 120
          • 121
          • 122
          • 123
          • 124

          AlipaySubmit.java模擬form表單請(qǐng)求支付寶支付接口的類

          package com.alipay.util;

          import java.io.IOException;

          import java.net.MalformedURLException;

          import java.net.URL;

          import java.util.ArrayList;

          import java.util.List;

          import java.util.Map;

          import org.dom4j.Document;

          import org.dom4j.DocumentException;

          import org.dom4j.Node;

          import org.dom4j.io.SAXReader;

          import com.alipay.config.AlipayConfig;

          import com.alipay.sign.MD5;

          /* *

          *類名:AlipaySubmit

          *功能:支付寶各接口請(qǐng)求提交類

          *詳細(xì):構(gòu)造支付寶各接口表單HTML文本,獲取遠(yuǎn)程HTTP數(shù)據(jù)

          *版本:3.3

          *日期:2012-08-13

          *說(shuō)明:

          *以下代碼只是為了方便商戶測(cè)試而提供的樣例代碼,商戶可以根據(jù)自己網(wǎng)站的需要,按照技術(shù)文檔編寫,并非一定要使用該代碼。

          *該代碼僅供學(xué)習(xí)和研究支付寶接口使用,只是提供一個(gè)參考。

          */

          public class AlipaySubmit {

          /**

          * 支付寶提供給商戶的服務(wù)接入網(wǎng)關(guān)URL(新)

          */

          private static final String ALIPAY_GATEWAY_NEW="https://mapi.alipay.com/gateway.do?";

          /**

          * 生成簽名結(jié)果

          * @param sPara 要簽名的數(shù)組

          * @return 簽名結(jié)果字符串

          */

          public static String buildRequestMysign(Map<String, String> sPara) {

          String prestr=AlipayCore.createLinkString(sPara); //把數(shù)組所有元素,按照“參數(shù)=參數(shù)值”的模式用“&”字符拼接成字符串

          String mysign="";

          if(AlipayConfig.sign_type.equals("MD5") ) {

          mysign=MD5.sign(prestr, AlipayConfig.key, AlipayConfig.input_charset);

          }

          return mysign;

          }

          /**

          * 生成要請(qǐng)求給支付寶的參數(shù)數(shù)組

          * @param sParaTemp 請(qǐng)求前的參數(shù)數(shù)組

          * @return 要請(qǐng)求的參數(shù)數(shù)組

          */

          private static Map<String, String> buildRequestPara(Map<String, String> sParaTemp) {

          //除去數(shù)組中的空值和簽名參數(shù)

          Map<String, String> sPara=AlipayCore.paraFilter(sParaTemp);

          //生成簽名結(jié)果

          String mysign=buildRequestMysign(sPara);

          //簽名結(jié)果與簽名方式加入請(qǐng)求提交參數(shù)組中

          sPara.put("sign", mysign);

          sPara.put("sign_type", AlipayConfig.sign_type);

          return sPara;

          }

          /**

          * 建立請(qǐng)求,以表單HTML形式構(gòu)造(默認(rèn))

          * @param sParaTemp 請(qǐng)求參數(shù)數(shù)組

          * @param strMethod 提交方式。兩個(gè)值可選:post、get

          * @param strButtonName 確認(rèn)按鈕顯示文字

          * @return 提交表單HTML文本

          */

          public static String buildRequest(Map<String, String> sParaTemp, String strMethod, String strButtonName) {

          //待請(qǐng)求參數(shù)數(shù)組

          Map<String, String> sPara=buildRequestPara(sParaTemp);

          List<String> keys=new ArrayList<String>(sPara.keySet());

          StringBuffer sbHtml=new StringBuffer();

          sbHtml.append("<form id=\"alipaysubmit\" name=\"alipaysubmit\" action=\"" + ALIPAY_GATEWAY_NEW

          + "_input_charset=" + AlipayConfig.input_charset + "\" method=\"" + strMethod

          + "\">");

          for (int i=0; i < keys.size(); i++) {

          String name=(String) keys.get(i);

          String value=(String) sPara.get(name);

          sbHtml.append("<input type=\"hidden\" name=\"" + name + "\" value=\"" + value + "\"/>");

          }

          //submit按鈕控件請(qǐng)不要含有name屬性

          sbHtml.append("<input type=\"submit\" value=\"" + strButtonName + "\" style=\"display:none;\"></form>");

          sbHtml.append("<script>document.forms['alipaysubmit'].submit();</script>");

          return sbHtml.toString();

          }

          /**

          * 用于防釣魚,調(diào)用接口query_timestamp來(lái)獲取時(shí)間戳的處理函數(shù)

          * 注意:遠(yuǎn)程解析XML出錯(cuò),與服務(wù)器是否支持SSL等配置有關(guān)

          * @return 時(shí)間戳字符串

          * @throws IOException

          * @throws DocumentException

          * @throws MalformedURLException

          */

          public static String query_timestamp() throws MalformedURLException,

          DocumentException, IOException {

          //構(gòu)造訪問(wèn)query_timestamp接口的URL串

          String strUrl=ALIPAY_GATEWAY_NEW + "service=query_timestamp&partner=" + AlipayConfig.partner + "&_input_charset" +AlipayConfig.input_charset;

          StringBuffer result=new StringBuffer();

          SAXReader reader=new SAXReader();

          Document doc=reader.read(new URL(strUrl).openStream());

          List<Node> nodeList=doc.selectNodes("http://alipay/*");

          for (Node node : nodeList) {

          // 截取部分不需要解析的信息

          if (node.getName().equals("is_success") && node.getText().equals("T")) {

          // 判斷是否有成功標(biāo)示

          List<Node> nodeList1=doc.selectNodes("http://response/timestamp/*");

          for (Node node1 : nodeList1) {

          result.append(node1.getText());

          }

          }

          }

          return result.toString();

          }

          }

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60
          • 61
          • 62
          • 63
          • 64
          • 65
          • 66
          • 67
          • 68
          • 69
          • 70
          • 71
          • 72
          • 73
          • 74
          • 75
          • 76
          • 77
          • 78
          • 79
          • 80
          • 81
          • 82
          • 83
          • 84
          • 85
          • 86
          • 87
          • 88
          • 89
          • 90
          • 91
          • 92
          • 93
          • 94
          • 95
          • 96
          • 97
          • 98
          • 99
          • 100
          • 101
          • 102
          • 103
          • 104
          • 105
          • 106
          • 107
          • 108
          • 109
          • 110
          • 111
          • 112
          • 113
          • 114
          • 115
          • 116
          • 117
          • 118
          • 119
          • 120
          • 121
          • 122
          • 123
          • 124
          • 125
          • 126
          • 127
          • 128
          • 129
          • 130
          • 131
          • 132
          • 133
          • 134
          • 135

          這幾個(gè)類調(diào)用支付寶接口的是AlipaySubmit,在網(wǎng)頁(yè)選好購(gòu)買的商品時(shí),在系統(tǒng)中生成訂單,然后進(jìn)行支付,瀏覽器跳轉(zhuǎn)到支付寶支付網(wǎng)站,Controller中代碼為:

          /**

          * 支付寶支付頁(yè)面

          *

          * @return

          * @throws IOException

          */

          @RequestMapping(value="/aliPay")

          public void aliPay(HttpServletRequest request, HttpServletResponse response) throws IOException {

          LOGGER.info("支付寶支付頁(yè)面");

          //商戶訂單號(hào),商戶網(wǎng)站訂單系統(tǒng)中唯一訂單號(hào),必填

          String orderNo=request.getParameter("orderNo");

          //訂單名稱,必填

          String subjectName=request.getParameter("subjectName");

          //付款金額,必填

          String total_fee=request.getParameter("fee");

          //商品描述,可空

          String body="法海風(fēng)控 " + subjectName;

          if ("money".equals(body)) {

          body="法海風(fēng)控 余額充值";

          }

          //把請(qǐng)求參數(shù)打包成map

          Map<String, String> sParaTemp=new HashMap<String, String>();

          sParaTemp.put("service", AlipayConfig.service);

          sParaTemp.put("partner", AlipayConfig.partner);

          sParaTemp.put("seller_id", AlipayConfig.seller_id);

          sParaTemp.put("_input_charset", AlipayConfig.input_charset);

          sParaTemp.put("payment_type", AlipayConfig.payment_type);

          sParaTemp.put("notify_url", AlipayConfig.notify_url);

          sParaTemp.put("return_url", AlipayConfig.return_url);

          sParaTemp.put("anti_phishing_key", AlipayConfig.anti_phishing_key);

          sParaTemp.put("exter_invoke_ip", AlipayConfig.exter_invoke_ip);

          sParaTemp.put("out_trade_no", orderNo);

          sParaTemp.put("subject", subjectName);

          sParaTemp.put("total_fee", total_fee);

          sParaTemp.put("body", body);

          //其他業(yè)務(wù)參數(shù)根據(jù)在線開(kāi)發(fā)文檔,添加參數(shù).文檔地址:https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.O9yorI&treeId=62&articleId=103740&docType=1

          //如sParaTemp.put("參數(shù)名","參數(shù)值");

          //建立請(qǐng)求

          String sHtmlText=AlipaySubmit.buildRequest(sParaTemp,"get","確認(rèn)");

          response.setHeader("Content-Type", "text/html; charset=UTF-8");

          response.setCharacterEncoding("UTF-8");

          PrintWriter out=response.getWriter();

          System.out.println(sHtmlText);

          out.println(sHtmlText);

          }

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46

          請(qǐng)求aliPay會(huì)跳轉(zhuǎn)到支付寶支付頁(yè)面:


          3、接收支付結(jié)果通知

          在配置好notify_url之后,支付結(jié)果會(huì)請(qǐng)求相應(yīng)的接口,我的是order/pay/aliPayOrder,代碼如下

          /**

          * 支付寶支付訂單

          * @return

          * @throws IOException

          */

          @ResponseBody

          @RequestMapping(value="pay/aliPayOrder", method=RequestMethod.POST)

          public void aliPayOrder(HttpServletRequest request,HttpServletResponse response) throws IOException {

          LOGGER.info("支付訂單");

          //從request中獲得參數(shù)Map,并返回可讀的Map

          Map<String, String> params=RequestUtil.getParameterMap(request);

          LOGGER.info(params.toString());

          //驗(yàn)證支付寶簽名

          boolean aliSign=AlipayNotify.verify(params);

          if (aliSign) {//驗(yàn)證成功

          //交易狀態(tài)

          String tradeStatus=params.get("trade_status");

          //訂單編號(hào)

          String orderNo=params.get("out_trade_no");

          //支付單號(hào)

          String payNo=params.get("trade_no");

          //支付賬號(hào)

          String payAccount=params.get("buyer_email");

          //支付金額

          String totalFee=params.get("total_fee");

          //收款支付寶賬號(hào)

          String sellerId=params.get("seller_id");

          if (Constant.ALIPAY_TRADE_SUCCESS.equals(tradeStatus)) {//支付寶支付狀態(tài)為成功

          //驗(yàn)證支付寶返回信息與請(qǐng)求信息一致

          if (ProInfoUtil.getInstance().getProperty("alipay_partner").equals(sellerId)) {

          //訂單處理狀態(tài)

          String orderHandleStatus="error";

          //驗(yàn)證訂單未做支付處理

          Order order=orderService.queryOrderByOrderNo(orderNo);

          //訂單已支付

          if (Constant.DEALSTATUS_PAY.equals(order.getDealStatus())) {

          response.getWriter().print("success");

          return;

          }

          if (null !=order && Double.parseDouble(totalFee)==order.getDealPrice() &&

          Constant.DEALSTATUS_NOT_PAY.equals(order.getDealStatus())) {//驗(yàn)證金額是否和訂單一致

          //更新訂單為已支付、更新用戶套餐余額、添加用戶充值記錄、添加用戶余額支出記錄

          order.setDealStatus(Constant.DEALSTATUS_PAY);

          order.setPayNo(payNo);

          order.setPayType(Constant.ALIPAY);

          order.setPayAccount(payAccount);

          try {

          //支付成功處理支付業(yè)務(wù)

          boolean result=orderService.payOrder(order);

          if (result) {

          //成功后向支付寶返回成功標(biāo)志

          LOGGER.info("支付寶支付成功");

          orderHandleStatus="success";

          response.getWriter().print("success");

          }

          } catch (Exception e) {

          e.printStackTrace();

          LOGGER.info("支付寶支付失敗");

          response.getWriter().print("fail");

          }

          }

          //添加支付信息

          Map<String, Object> map=new HashMap<String, Object>();

          map.put("params", params.toString());

          map.put("payType", Constant.ALIPAY);

          map.put("orderNo", orderNo);

          map.put("handleStatus", orderHandleStatus);

          orderService.addPayInfo(map);

          }

          }

          } else {//驗(yàn)證失敗

          LOGGER.info("支付寶返回驗(yàn)證失敗");

          response.getWriter().print("fail");

          }

          }

          /**

          * 從request中獲得參數(shù)Map,并返回可讀的Map

          *

          * @param request

          * @return

          */

          @SuppressWarnings("unchecked")

          public static Map getParameterMap(HttpServletRequest request) {

          // 參數(shù)Map

          Map properties=request.getParameterMap();

          // 返回值Map

          Map<String, String> returnMap=new HashMap<String, String>();

          Iterator entries=properties.entrySet().iterator();

          Map.Entry entry;

          String name="";

          String value="";

          while (entries.hasNext()) {

          entry=(Map.Entry) entries.next();

          name=(String) entry.getKey();

          Object valueObj=entry.getValue();

          if(null==valueObj){

          value="";

          }else if(valueObj instanceof String[]){

          String[] values=(String[])valueObj;

          for(int i=0;i<values.length;i++){

          value=values[i] + ",";

          }

          value=value.substring(0, value.length()-1);

          }else{

          value=valueObj.toString();

          }

          returnMap.put(name, value);

          }

          return returnMap;

          }

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60
          • 61
          • 62
          • 63
          • 64
          • 65
          • 66
          • 67
          • 68
          • 69
          • 70
          • 71
          • 72
          • 73
          • 74
          • 75
          • 76
          • 77
          • 78
          • 79
          • 80
          • 81
          • 82
          • 83
          • 84
          • 85
          • 86
          • 87
          • 88
          • 89
          • 90
          • 91
          • 92
          • 93
          • 94
          • 95
          • 96
          • 97
          • 98
          • 99
          • 100
          • 101
          • 102
          • 103
          • 104
          • 105
          • 106
          • 107
          • 108
          • 109
          • 110
          • 111
          • 112
          • 113
          • 114
          • 115

          至此,支付寶支付功能已經(jīng)做完了,其中有幾個(gè)細(xì)節(jié)需要添加,比如支付時(shí)查詢訂單狀態(tài)是否已經(jīng)支付,是否過(guò)期等等,可以根據(jù)自己的需求去完善。

          支付寶的接入還是很順利的,如果熟練的話一兩天就可以完成了,剛開(kāi)始寫博客,有錯(cuò)誤或者不明白的地方歡迎大家指出一起交流學(xué)習(xí),共同進(jìn)步。

          由于篇幅問(wèn)題,我在下一章介紹微信支付的接入。


          Dreamweaver中實(shí)現(xiàn)掃描二維碼支付,支付成功后進(jìn)入指定功能頁(yè)面,通常需要以下幾個(gè)步驟:

          1. 1.
          2. 生成二維碼:首先,你需要生成一個(gè)包含支付信息的二維碼。這通常涉及到后端服務(wù),它會(huì)根據(jù)支付請(qǐng)求生成一個(gè)二維碼圖片,并將支付信息存儲(chǔ)在服務(wù)器上。
          3. 2.
          4. 用戶掃描二維碼:用戶使用微信或其他支付應(yīng)用掃描二維碼,完成支付。
          5. 3.
          6. 支付狀態(tài)回調(diào):支付完成后,支付平臺(tái)會(huì)向你的服務(wù)器發(fā)送一個(gè)支付成功的回調(diào)通知。這個(gè)通知通常包含支付結(jié)果和訂單信息。
          7. 4.
          8. 服務(wù)器處理回調(diào):你的服務(wù)器接收到支付成功的回調(diào)后,需要驗(yàn)證回調(diào)信息的合法性,并更新訂單狀態(tài)為已支付。
          9. 5.
          10. 頁(yè)面跳轉(zhuǎn):一旦訂單狀態(tài)更新為已支付,服務(wù)器可以生成一個(gè)包含支付成功信息的頁(yè)面,并通過(guò)HTTP重定向或AJAX請(qǐng)求將用戶引導(dǎo)到這個(gè)頁(yè)面。

          在Dreamweaver中,你可以使用HTML、CSS和JavaScript來(lái)創(chuàng)建用戶界面,并通過(guò)AJAX與服務(wù)器進(jìn)行交互。以下是一個(gè)簡(jiǎn)化的示例流程:

          • HTML頁(yè)面:創(chuàng)建一個(gè)包含二維碼的HTML頁(yè)面,用戶可以掃描這個(gè)二維碼進(jìn)行支付。


          • 服務(wù)器端處理:在服務(wù)器端,你需要編寫代碼來(lái)處理支付回調(diào),并在支付成功后更新訂單狀態(tài),并生成一個(gè)支付成功的頁(yè)面。


          • 頁(yè)面跳轉(zhuǎn):在支付成功后,服務(wù)器返回的頁(yè)面中可以包含一個(gè)JavaScript代碼,用于在支付成功后自動(dòng)跳轉(zhuǎn)到指定的功能頁(yè)面。

          請(qǐng)注意,這只是一個(gè)簡(jiǎn)化的示例,實(shí)際的實(shí)現(xiàn)可能會(huì)更復(fù)雜,需要考慮安全性、用戶體驗(yàn)和錯(cuò)誤處理等因素。此外,具體的實(shí)現(xiàn)細(xì)節(jié)會(huì)根據(jù)你使用的支付平臺(tái)和后端技術(shù)棧有所不同。在實(shí)際開(kāi)發(fā)中,你可能需要查閱支付平臺(tái)的開(kāi)發(fā)文檔,了解如何生成二維碼、處理支付回調(diào)以及如何與前端頁(yè)面進(jìn)行交互。有需要完整源碼的朋友,加關(guān)注線下溝通。

          附:代碼僅供需要的朋友參考(為便于展示顯示圖片效果)

          支付成功后,微信異步回調(diào)頁(yè)面為notify_wxpay.php,在根目錄中,可根據(jù)情況修改

          微信支付功能開(kāi)發(fā)


          主站蜘蛛池模板: 日本一区二区视频| 久久免费区一区二区三波多野| 中文字幕在线视频一区| 大香伊人久久精品一区二区| 无码人妻精品一区二区三| 亚洲乱码日产一区三区| 中文字幕一区在线观看| 在线观看国产区亚洲一区成人| 日本中文字幕在线视频一区| 一区二区三区国模大胆| 国产在线不卡一区二区三区 | 精品一区二区三区在线观看| 亚洲一区二区视频在线观看| av一区二区三区人妻少妇| 日本一道一区二区免费看| 国产精品美女一区二区| 农村人乱弄一区二区| 国99精品无码一区二区三区| 水蜜桃av无码一区二区| 无码一区18禁3D| 日本一区二区三区精品国产 | 久久精品黄AA片一区二区三区| 久久久久人妻精品一区| 无码人妻一区二区三区兔费| 日韩十八禁一区二区久久| 精品国产一区二区三区久久| 亚洲综合一区二区| 国产伦精品一区二区三区免费下载| 无码人妻精品一区二区三区99不卡 | 日本一区二区在线| 亚洲综合在线一区二区三区| 国产AV天堂无码一区二区三区| 狠狠综合久久AV一区二区三区| 91在线视频一区| 精品视频一区二区| 久久久精品人妻一区二区三区蜜桃| 国产婷婷色一区二区三区深爱网| 亚洲午夜福利AV一区二区无码| 中文字幕乱码一区久久麻豆樱花 | 无码人妻AⅤ一区二区三区水密桃| 无码国产伦一区二区三区视频 |