支付宝封装

 

Android封装支付宝支付

  1739人阅读  评论(3)  收藏  举报
  分类:
 

在做Android支付的时候肯定会用到支付宝支付, 根据官方给出的demo做起来非常费劲,所以我们需要一次简单的封装。 
封装的代码也很简单,就是将官网给的demo提取出一个类来方便使用。

[java]  view plain  copy
  1. /** 
  2.  * 支付宝支付 
  3.  *  
  4.  * @author lenovo 
  5.  */  
  6. public class Alipay {  
  7.     // 商户PID  
  8.     public static final String PARTNER = "123456789";  
  9.     // 商户收款账号  
  10.     public static final String SELLER = "qibin0506@gmail.com";  
  11.     // 商户私钥,pkcs8格式  
  12.     public static final String RSA_PRIVATE = "rsa_private";  
  13.     // 支付宝公钥  
  14.     public static final String RSA_PUBLIC = "rsa_public";  
  15.   
  16.     private static final int SDK_PAY_FLAG = 1;  
  17.   
  18.     private WeakReference<Activity> mActivity;  
  19.   
  20.     private OnAlipayListener mListener;  
  21.   
  22.     public Alipay(Activity activity) {  
  23.         mActivity = new WeakReference<Activity>(activity);  
  24.     }  
  25.   
  26.     @SuppressLint("HandlerLeak")   
  27.     private Handler mHandler = new Handler() {  
  28.         public void handleMessage(Message msg) {  
  29.             if (msg.what == SDK_PAY_FLAG) {  
  30.                 PayResult payResult = new PayResult((String) msg.obj);  
  31.                 // 支付宝返回此次支付结果及加签,建议对支付宝签名信息拿签约时支付宝提供的公钥做验签  
  32.                 String resultInfo = payResult.getResult();  
  33.                 String resultStatus = payResult.getResultStatus();  
  34.                 // 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档  
  35.                 if (TextUtils.equals(resultStatus, "9000")) {  
  36.                     if (mListener != null) mListener.onSuccess();  
  37.                 } else {  
  38.                     // 判断resultStatus 为非“9000”则代表可能支付失败  
  39.                     // “8000”代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,  
  40.                     // 最终交易是否成功以服务端异步通知为准(小概率状态)  
  41.                     if (TextUtils.equals(resultStatus, "8000")) {  
  42.                         if (mListener != null) mListener.onWait();  
  43.                     } else {  
  44.                         // 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误  
  45.                         if (mListener != null) mListener.onCancel();  
  46.                     }  
  47.                 }  
  48.             }  
  49.         }  
  50.     };  
  51.   
  52.     /** 
  53.      * 支付 
  54.      *  
  55.      * @param title   标题 不能为空或者“” 
  56.      * @param desc  描述 不能为空或者“” 
  57.      * @param price 价格 不能为空或者“” 
  58.      * @param sn  商品唯一货号 不能为空或者“” 
  59.      * @param url 服务器回调url 不能为空或者“” 
  60.      */  
  61.     public void pay(String title, String desc, String price, String sn, String url) {  
  62.         // 订单  
  63.         String orderInfo = getOrderInfo(title, desc, price, sn, url);  
  64.   
  65.         // 对订单做RSA 签名  
  66.         String sign = sign(orderInfo);  
  67.         try {  
  68.             // 仅需对sign 做URL编码  
  69.             sign = URLEncoder.encode(sign, "UTF-8");  
  70.         } catch (UnsupportedEncodingException e) {  
  71.             e.printStackTrace();  
  72.         }  
  73.   
  74.         // 完整的符合支付宝参数规范的订单信息  
  75.         final String payInfo = orderInfo + "&sign=\"" + sign + "\"&"  
  76.                 + getSignType();  
  77.   
  78.         Runnable payRunnable = new Runnable() {  
  79.   
  80.             @Override  
  81.             public void run() {  
  82.                 Activity activity = mActivity.get();  
  83.                 if(activity == nullreturn;  
  84.                 // 构造PayTask 对象  
  85.                 PayTask alipay = new PayTask(activity);  
  86.                 // 调用支付接口,获取支付结果  
  87.                 String result = alipay.pay(payInfo);  
  88.   
  89.                 Message msg = new Message();  
  90.                 msg.what = SDK_PAY_FLAG;  
  91.                 msg.obj = result;  
  92.                 mHandler.sendMessage(msg);  
  93.             }  
  94.         };  
  95.   
  96.         // 必须异步调用  
  97.         Thread payThread = new Thread(payRunnable);  
  98.         payThread.start();  
  99.     }  
  100.   
  101.     /** 
  102.      * create the order info. 创建订单信息 
  103.      *  
  104.      */  
  105.     public String getOrderInfo(String subject, String body, String price,  
  106.             String sn, String url) {  
  107.         // 签约合作者身份ID  
  108.         String orderInfo = "partner=" + "\"" + PARTNER + "\"";  
  109.   
  110.         // 签约卖家支付宝账号  
  111.         orderInfo += "&seller_id=" + "\"" + SELLER + "\"";  
  112.   
  113.         // 商户网站唯一订单号  
  114.         orderInfo += "&out_trade_no=" + "\"" + sn + "\"";  
  115.   
  116.         // 商品名称  
  117.         orderInfo += "&subject=" + "\"" + subject + "\"";  
  118.   
  119.         // 商品详情  
  120.         orderInfo += "&body=" + "\"" + body + "\"";  
  121.   
  122.         // 商品金额  
  123.         orderInfo += "&total_fee=" + "\"" + price + "\"";  
  124.   
  125.         // 服务器异步通知页面路径  
  126.         orderInfo += "¬ify_url=" + "\"" + url + "\"";  
  127.   
  128.         // 服务接口名称, 固定值  
  129.         orderInfo += "&service=\"mobile.securitypay.pay\"";  
  130.   
  131.         // 支付类型, 固定值  
  132.         orderInfo += "&payment_type=\"1\"";  
  133.   
  134.         // 参数编码, 固定值  
  135.         orderInfo += "&_input_charset=\"utf-8\"";  
  136.   
  137.         // 设置未付款交易的超时时间  
  138.         // 默认30分钟,一旦超时,该笔交易就会自动被关闭。  
  139.         // 取值范围:1m~15d。  
  140.         // m-分钟,h-小时,d-天,1c-当天(无论交易何时创建,都在0点关闭)。  
  141.         // 该参数数值不接受小数点,如1.5h,可转换为90m。  
  142.         orderInfo += "&it_b_pay=\"30m\"";  
  143.   
  144.         // extern_token为经过快登授权获取到的alipay_open_id,带上此参数用户将使用授权的账户进行支付  
  145.         // orderInfo += "&extern_token=" + "\"" + extern_token + "\"";  
  146.   
  147.         // 支付宝处理完请求后,当前页面跳转到商户指定页面的路径,可空  
  148.         orderInfo += "&return_url=\"m.alipay.com\"";  
  149.   
  150.         // 调用银行卡支付,需配置此参数,参与签名, 固定值 (需要签约《无线银行卡快捷支付》才能使用)  
  151.         // orderInfo += "&paymethod=\"expressGateway\"";  
  152.   
  153.         return orderInfo;  
  154.     }  
  155.   
  156.     /** 
  157.      * sign the order info. 对订单信息进行签名 
  158.      *  
  159.      * @param content 
  160.      *            待签名订单信息 
  161.      */  
  162.     public String sign(String content) {  
  163.         return SignUtils.sign(content, RSA_PRIVATE);  
  164.     }  
  165.   
  166.     /** 
  167.      * get the sign type we use. 获取签名方式 
  168.      *  
  169.      */  
  170.     public String getSignType() {  
  171.         return "sign_type=\"RSA\"";  
  172.     }  
  173.   
  174.     public void setListener(OnAlipayListener l) {  
  175.         mListener = l;  
  176.     }  
  177.   
  178.     /** 
  179.      * 支付回调接口 
  180.      *  
  181.      * @author lenovo 
  182.      *  
  183.      */  
  184.     public static class OnAlipayListener {  
  185.         /** 
  186.          * 支付成功 
  187.          */  
  188.         public void onSuccess() {}  
  189.   
  190.         /** 
  191.          * 支付取消 
  192.          */  
  193.         public void onCancel() {}  
  194.   
  195.         /** 
  196.          * 等待确认 
  197.          */  
  198.         public void onWait() {}  
  199.     }  
  200. }  
  201.   
  202. final class Base64 {  
  203.   
  204.     private static final int BASELENGTH = 128;  
  205.     private static final int LOOKUPLENGTH = 64;  
  206.     private static final int TWENTYFOURBITGROUP = 24;  
  207.     private static final int EIGHTBIT = 8;  
  208.     private static final int SIXTEENBIT = 16;  
  209.     private static final int FOURBYTE = 4;  
  210.     private static final int SIGN = -128;  
  211.     private static char PAD = '=';  
  212.     private static byte[] base64Alphabet = new byte[BASELENGTH];  
  213.     private static char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];  
  214.   
  215.     static {  
  216.         for (int i = 0; i < BASELENGTH; ++i) {  
  217.             base64Alphabet[i] = -1;  
  218.         }  
  219.         for (int i = 'Z'; i >= 'A'; i--) {  
  220.             base64Alphabet[i] = (byte) (i - 'A');  
  221.         }  
  222.         for (int i = 'z'; i >= 'a'; i--) {  
  223.             base64Alphabet[i] = (byte) (i - 'a' + 26);  
  224.         }  
  225.   
  226.         for (int i = '9'; i >= '0'; i--) {  
  227.             base64Alphabet[i] = (byte) (i - '0' + 52);  
  228.         }  
  229.   
  230.         base64Alphabet['+'] = 62;  
  231.         base64Alphabet['/'] = 63;  
  232.   
  233.         for (int i = 0; i <= 25; i++) {  
  234.             lookUpBase64Alphabet[i] = (char) ('A' + i);  
  235.         }  
  236.   
  237.         for (int i = 26, j = 0; i <= 51; i++, j++) {  
  238.             lookUpBase64Alphabet[i] = (char) ('a' + j);  
  239.         }  
  240.   
  241.         for (int i = 52, j = 0; i <= 61; i++, j++) {  
  242.             lookUpBase64Alphabet[i] = (char) ('0' + j);  
  243.         }  
  244.         lookUpBase64Alphabet[62] = (char'+';  
  245.         lookUpBase64Alphabet[63] = (char'/';  
  246.   
  247.     }  
  248.   
  249.     private static boolean isWhiteSpace(char octect) {  
  250.         return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);  
  251.     }  
  252.   
  253.     private static boolean isPad(char octect) {  
  254.         return (octect == PAD);  
  255.     }  
  256.   
  257.     private static boolean isData(char octect) {  
  258.         return (octect < BASELENGTH && base64Alphabet[octect] != -1);  
  259.     }  
  260.   
  261.     /** 
  262.      * Encodes hex octects into Base64 
  263.      *  
  264.      * @param binaryData 
  265.      *            Array containing binaryData 
  266.      * @return Encoded Base64 array 
  267.      */  
  268.     public static String encode(byte[] binaryData) {  
  269.   
  270.         if (binaryData == null) {  
  271.             return null;  
  272.         }  
  273.   
  274.         int lengthDataBits = binaryData.length * EIGHTBIT;  
  275.         if (lengthDataBits == 0) {  
  276.             return "";  
  277.         }  
  278.   
  279.         int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;  
  280.         int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;  
  281.         int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1  
  282.                 : numberTriplets;  
  283.         char encodedData[] = null;  
  284.   
  285.         encodedData = new char[numberQuartet * 4];  
  286.   
  287.         byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;  
  288.   
  289.         int encodedIndex = 0;  
  290.         int dataIndex = 0;  
  291.   
  292.         for (int i = 0; i < numberTriplets; i++) {  
  293.             b1 = binaryData[dataIndex++];  
  294.             b2 = binaryData[dataIndex++];  
  295.             b3 = binaryData[dataIndex++];  
  296.   
  297.             l = (byte) (b2 & 0x0f);  
  298.             k = (byte) (b1 & 0x03);  
  299.   
  300.             byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)  
  301.                     : (byte) ((b1) >> 2 ^ 0xc0);  
  302.             byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)  
  303.                     : (byte) ((b2) >> 4 ^ 0xf0);  
  304.             byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6)  
  305.                     : (byte) ((b3) >> 6 ^ 0xfc);  
  306.   
  307.             encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];  
  308.             encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];  
  309.             encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];  
  310.             encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];  
  311.         }  
  312.   
  313.         // form integral number of 6-bit groups  
  314.         if (fewerThan24bits == EIGHTBIT) {  
  315.             b1 = binaryData[dataIndex];  
  316.             k = (byte) (b1 & 0x03);  
  317.   
  318.             byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)  
  319.                     : (byte) ((b1) >> 2 ^ 0xc0);  
  320.             encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];  
  321.             encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];  
  322.             encodedData[encodedIndex++] = PAD;  
  323.             encodedData[encodedIndex++] = PAD;  
  324.         } else if (fewerThan24bits == SIXTEENBIT) {  
  325.             b1 = binaryData[dataIndex];  
  326.             b2 = binaryData[dataIndex + 1];  
  327.             l = (byte) (b2 & 0x0f);  
  328.             k = (byte) (b1 & 0x03);  
  329.   
  330.             byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)  
  331.                     : (byte) ((b1) >> 2 ^ 0xc0);  
  332.             byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)  
  333.                     : (byte) ((b2) >> 4 ^ 0xf0);  
  334.   
  335.             encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];  
  336.             encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];  
  337.             encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];  
  338.             encodedData[encodedIndex++] = PAD;  
  339.         }  
  340.   
  341.         return new String(encodedData);  
  342.     }  
  343.   
  344.     /** 
  345.      * Decodes Base64 data into octects 
  346.      *  
  347.      * @param encoded 
  348.      *            string containing Base64 data 
  349.      * @return Array containind decoded data. 
  350.      */  
  351.     public static byte[] decode(String encoded) {  
  352.   
  353.         if (encoded == null) {  
  354.             return null;  
  355.         }  
  356.   
  357.         char[] base64Data = encoded.toCharArray();  
  358.         // remove white spaces  
  359.         int len = removeWhiteSpace(base64Data);  
  360.   
  361.         if (len % FOURBYTE != 0) {  
  362.             return null;// should be divisible by four  
  363.         }  
  364.   
  365.         int numberQuadruple = (len / FOURBYTE);  
  366.   
  367.         if (numberQuadruple == 0) {  
  368.             return new byte[0];  
  369.         }  
  370.   
  371.         byte decodedData[] = null;  
  372.         byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;  
  373.         char d1 = 0, d2 = 0, d3 = 0, d4 = 0;  
  374.   
  375.         int i = 0;  
  376.         int encodedIndex = 0;  
  377.         int dataIndex = 0;  
  378.         decodedData = new byte[(numberQuadruple) * 3];  
  379.   
  380.         for (; i < numberQuadruple - 1; i++) {  
  381.   
  382.             if (!isData((d1 = base64Data[dataIndex++]))  
  383.                     || !isData((d2 = base64Data[dataIndex++]))  
  384.                     || !isData((d3 = base64Data[dataIndex++]))  
  385.                     || !isData((d4 = base64Data[dataIndex++]))) {  
  386.                 return null;  
  387.             }// if found "no data" just return null  
  388.   
  389.             b1 = base64Alphabet[d1];  
  390.             b2 = base64Alphabet[d2];  
  391.             b3 = base64Alphabet[d3];  
  392.             b4 = base64Alphabet[d4];  
  393.   
  394.             decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);  
  395.             decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));  
  396.             decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);  
  397.         }  
  398.   
  399.         if (!isData((d1 = base64Data[dataIndex++]))  
  400.                 || !isData((d2 = base64Data[dataIndex++]))) {  
  401.             return null;// if found "no data" just return null  
  402.         }  
  403.   
  404.         b1 = base64Alphabet[d1];  
  405.         b2 = base64Alphabet[d2];  
  406.   
  407.         d3 = base64Data[dataIndex++];  
  408.         d4 = base64Data[dataIndex++];  
  409.         if (!isData((d3)) || !isData((d4))) {// Check if they are PAD characters  
  410.             if (isPad(d3) && isPad(d4)) {  
  411.                 if ((b2 & 0xf) != 0)// last 4 bits should be zero  
  412.                 {  
  413.                     return null;  
  414.                 }  
  415.                 byte[] tmp = new byte[i * 3 + 1];  
  416.                 System.arraycopy(decodedData, 0, tmp, 0, i * 3);  
  417.                 tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);  
  418.                 return tmp;  
  419.             } else if (!isPad(d3) && isPad(d4)) {  
  420.                 b3 = base64Alphabet[d3];  
  421.                 if ((b3 & 0x3) != 0)// last 2 bits should be zero  
  422.                 {  
  423.                     return null;  
  424.                 }  
  425.                 byte[] tmp = new byte[i * 3 + 2];  
  426.                 System.arraycopy(decodedData, 0, tmp, 0, i * 3);  
  427.                 tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);  
  428.                 tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));  
  429.                 return tmp;  
  430.             } else {  
  431.                 return null;  
  432.             }  
  433.         } else { // No PAD e.g 3cQl  
  434.             b3 = base64Alphabet[d3];  
  435.             b4 = base64Alphabet[d4];  
  436.             decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);  
  437.             decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));  
  438.             decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);  
  439.   
  440.         }  
  441.   
  442.         return decodedData;  
  443.     }  
  444.   
  445.     /** 
  446.      * remove WhiteSpace from MIME containing encoded Base64 data. 
  447.      *  
  448.      * @param data 
  449.      *            the byte array of base64 data (with WS) 
  450.      * @return the new length 
  451.      */  
  452.     private static int removeWhiteSpace(char[] data) {  
  453.         if (data == null) {  
  454.             return 0;  
  455.         }  
  456.   
  457.         // count characters that's not whitespace  
  458.         int newSize = 0;  
  459.         int len = data.length;  
  460.         for (int i = 0; i < len; i++) {  
  461.             if (!isWhiteSpace(data[i])) {  
  462.                 data[newSize++] = data[i];  
  463.             }  
  464.         }  
  465.         return newSize;  
  466.     }  
  467. }  
  468.   
  469. class PayResult {  
  470.     private String resultStatus;  
  471.     private String result;  
  472.     private String memo;  
  473.   
  474.     public PayResult(String rawResult) {  
  475.   
  476.         if (TextUtils.isEmpty(rawResult))  
  477.             return;  
  478.   
  479.         String[] resultParams = rawResult.split(";");  
  480.         for (String resultParam : resultParams) {  
  481.             if (resultParam.startsWith("resultStatus")) {  
  482.                 resultStatus = gatValue(resultParam, "resultStatus");  
  483.             }  
  484.             if (resultParam.startsWith("result")) {  
  485.                 result = gatValue(resultParam, "result");  
  486.             }  
  487.             if (resultParam.startsWith("memo")) {  
  488.                 memo = gatValue(resultParam, "memo");  
  489.             }  
  490.         }  
  491.     }  
  492.   
  493.     @Override  
  494.     public String toString() {  
  495.         return "resultStatus={" + resultStatus + "};memo={" + memo  
  496.                 + "};result={" + result + "}";  
  497.     }  
  498.   
  499.     private String gatValue(String content, String key) {  
  500.         String prefix = key + "={";  
  501.         return content.substring(content.indexOf(prefix) + prefix.length(),  
  502.                 content.lastIndexOf("}"));  
  503.     }  
  504.   
  505.     /** 
  506.      * @return the resultStatus 
  507.      */  
  508.     public String getResultStatus() {  
  509.         return resultStatus;  
  510.     }  
  511.   
  512.     /** 
  513.      * @return the memo 
  514.      */  
  515.     public String getMemo() {  
  516.         return memo;  
  517.     }  
  518.   
  519.     /** 
  520.      * @return the result 
  521.      */  
  522.     public String getResult() {  
  523.         return result;  
  524.     }  
  525. }  
  526.   
  527. class SignUtils {  
  528.   
  529.     private static final String ALGORITHM = "RSA";  
  530.   
  531.     private static final String SIGN_ALGORITHMS = "SHA1WithRSA";  
  532.   
  533.     private static final String DEFAULT_CHARSET = "UTF-8";  
  534.   
  535.     public static String sign(String content, String privateKey) {  
  536.         try {  
  537.             PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(  
  538.                     Base64.decode(privateKey));  
  539.             KeyFactory keyf = KeyFactory.getInstance(ALGORITHM);  
  540.             PrivateKey priKey = keyf.generatePrivate(priPKCS8);  
  541.   
  542.             java.security.Signature signature = java.security.Signature  
  543.                     .getInstance(SIGN_ALGORITHMS);  
  544.   
  545.             signature.initSign(priKey);  
  546.             signature.update(content.getBytes(DEFAULT_CHARSET));  
  547.   
  548.             byte[] signed = signature.sign();  
  549.   
  550.             return Base64.encode(signed);  
  551.         } catch (Exception e) {  
  552.             e.printStackTrace();  
  553.         }  
  554.   
  555.         return null;  
  556.     }  
  557. }  


 

前面的几个常量是需要去支付宝官网获取的,获取后直接替换就ok, 
其他的代码基本都是从demo中copy出来的, 现在我们就将支付功能封装到了一个类中,那么如何使用呢?

[java]  view plain  copy
  1. Alipay alipay = new Alipay(OrderConfirmActivity.this);  
  2. alipay.setListener(mAlipayListener);  
  3. alipay.pay(desc, mOrder.getShopName(), String.valueOf(orderAmount), orderSn, url);  
  4. /** 
  5.  * 支付宝支付回调 
  6.  */  
  7. private Alipay.OnAlipayListener mAlipayListener = new Alipay.OnAlipayListener() {  
  8.     @Override  
  9.     public void onSuccess() {  
  10.         onOrderSubmitSuccess();  
  11.     }  
  12.   
  13.     @Override  
  14.     public void onCancel() {  
  15.         onUserOrderCanceled();  
  16.             Toast.makeText(OrderConfirmActivity.this, R.string.pay_failed,   
  17.                     Toast.LENGTH_SHORT).show();  
  18.     }  
  19.   
  20.     @Override  
  21.     public void onWait() {  
  22.   
  23.     }  
  24. };  


 

new出对象来,只需要调用pay方法就ok啦, 不过支付的回调我们还是必须的,当然这个也不麻烦。这里说一下pay方法的几个参数,

  1. title 支付的标题
  2. desc 支付的描述
  3. price 支付的金额
  4. sn 商品的唯一货号
  5. url 服务器的回调url

这几个参数在做支付的时候服务器都会给到,但是要注意一下,这几个参数都不能为空或者空字符串,否则会支付失败。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值