微信支付与支付宝支付
花了几天的时间将支付宝与微信支付都弄完了,中间遇到了不少坑。尤其是在微信支付的时候,于是决定写2遍博客给大家介绍一下。
1.支付宝支付
基本配置文件
服务器加签文档
官方demo
<一>基本配置文件
// 商户PID public static final String PARTNER = PayKeys.DEFAULT_PARTNER; // 商户收款账号 public static final String SELLER = PayKeys.DEFAULT_SELLER; // 商户私钥,pkcs8格式 public static final String RSA_PRIVATE = PayKeys.PRIVATE; // 支付宝公钥 public static final String RSA_PUBLIC = ""; private static final int SDK_PAY_FLAG = 1;
需要向公司申请的几样信息
package com.alipay.sdk.pay.demo; /** * Created by Administrator on 2015/9/28. * 提示:如何获取安全校验码和合作身份者id * 1.用您的签约支付宝账号登录支付宝网站(www.alipay.com) * 2.点击“商家服务”(https://b.alipay.com/order/myorder.htm) * 3.点击“查询合作者身份(pid)”、“查询安全校验码(key)” */ public class PayKeys { // // 请参考 Android平台安全支付服务(msp)应用开发接口(4.2 RSA算法签名)部分,并使用压缩包中的openssl RSA密钥生成工具,生成一套RSA公私钥。 // 这里签名时,只需要使用生成的RSA私钥。 // Note: 为安全起见,使用RSA私钥进行签名的操作过程,应该尽量放到商家服务器端去进行。 //合作身份者id,以2088开头的16位纯数字 此id用来支付时快速登录 public static final String DEFAULT_PARTNER = "2088011085074233"; //收款支付宝账号 public static final String DEFAULT_SELLER = "917356107@qq.com"; //商户私钥,自助生成,在压缩包中有openssl,用此软件生成商户的公钥和私钥,写到此处要不然服务器返回错误。公钥要传到淘宝合作账户里详情请看淘宝的sdk文档 public static final String PRIVATE = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL51jaxQhxW9PnWpW+nz6yJ76tp9eGFXmfGnuxMK+Pmx/qavdsewXOLBfI2OSCR39TzxwMYvCmUrnrt0fVSa7mblbNos2FnMM9ijnx8bsAAhm+i7BKhuaHMunJKH69L+D753zH3P1YIh0ly5DnAr3WPqHydp384qBvb8NS9Tay0HAgMBAAECgYB82PIVknP6fCMFXg8yPQJViIVa1ASlSpdPIXQv93FdvKABA+QI4kMBIXRUFoCT506KtK55OzzFNOLIXoQJgcXj69z0l6pmjJJgXMaBW/9rOzelot13CiGatrIrGngEZO+bCBTud/jQA598zjZ1g182tT+FLDL7GIftW2hC8GqtAQJBAN+XrYsyfL+uSmLdAVEz1vzziU1naGr10Msm1jMnnO/JYdB+84j7FSHxsQ4YOgsmeN5YVsJcVfc/CReOxknns38CQQDaEHnVPDt+Z7sqT7bN0UKh0/CrqkDTiIjhz1lJyIIoqVRoeJjJn1wlEKBV5R9gkTJutQTVU19XFtblMEnOy6p5AkEAw170rEmMSa0QoHw+d2bVtydR1QnDapqqO6kOx5oYfkm4J4eWYx4J5CQdMpSmuzF9scL85E3sa+NvnV8LEm7cHwJALtXzFPWG4bNt47yTSslzQka/Hl/G5Kginj1mtA44xnr4AihEyKlNpThY95nqj1cgOd7vVtI9W/sv1LH2aFAeIQJBAIqXbMc6xGVfuiFAJKtg+AFNMBP0UOEgMEoKo4RPFp21nBhFgL9/WYM4ZjyHUdr45rCySAqQovw4DCHLfQZC23I="; //公钥 public static final String PUBLIC = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+dY2sUIcVvT51qVvp8+sie+rafXhhV5nxp7sTCvj5sf6mr3bHsFziwXyNjkgkd/U88cDGLwplK567dH1Umu5m5WzaLNhZzDPYo58fG7AAIZvouwSobmhzLpySh+vS/g++d8x9z9WCIdJcuQ5wK91j6h8nad/OKgb2/DUvU2stBwIDAQAB"; }
测试的时候本地加签,本地运行成功之后再用服务器传来的加签信息
这是官方的demo进行改编的。
运行时遇到问题可以将问题发给我,1136991629@qq.com
package com.alipay.sdk.pay.demo; public final class Base64 {private static final int BASELENGTH = 128; private static final int LOOKUPLENGTH = 64; private static final int TWENTYFOURBITGROUP = 24; private static final int EIGHTBIT = 8; private static final int SIXTEENBIT = 16; private static final int FOURBYTE = 4; private static final int SIGN = -128; private static char PAD = '='; private static byte[] base64Alphabet = new byte[BASELENGTH]; private static char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH]; static {for (int i = 0; i < BASELENGTH; ++i) {base64Alphabet[i] = -1; }for (int i = 'Z'; i >= 'A'; i--) {base64Alphabet[i] = (byte) (i - 'A'); }for (int i = 'z'; i >= 'a'; i--) {base64Alphabet[i] = (byte) (i - 'a' + 26); }for (int i = '9'; i >= '0'; i--) {base64Alphabet[i] = (byte) (i - '0' + 52); }base64Alphabet['+'] = 62; base64Alphabet['/'] = 63; for (int i = 0; i <= 25; i++) {lookUpBase64Alphabet[i] = (char) ('A' + i); }for (int i = 26, j = 0; i <= 51; i++, j++) {lookUpBase64Alphabet[i] = (char) ('a' + j); }for (int i = 52, j = 0; i <= 61; i++, j++) {lookUpBase64Alphabet[i] = (char) ('0' + j); }lookUpBase64Alphabet[62] = (char) '+'; lookUpBase64Alphabet[63] = (char) '/'; }private static boolean isWhiteSpace(char octect) {return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); }private static boolean isPad(char octect) {return (octect == PAD); }private static boolean isData(char octect) {return (octect < BASELENGTH && base64Alphabet[octect] != -1); }/** * Encodes hex octects into Base64 * * @param binaryData * Array containing binaryData * @return Encoded Base64 array */ public static String encode(byte[] binaryData) {if (binaryData == null) {return null; }int lengthDataBits = binaryData.length * EIGHTBIT; if (lengthDataBits == 0) {return ""; }int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP; int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP; int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets; char encodedData[] = null; encodedData = new char[numberQuartet * 4]; byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0; int encodedIndex = 0; int dataIndex = 0; for (int i = 0; i < numberTriplets; i++) {b1 = binaryData[dataIndex++]; b2 = binaryData[dataIndex++]; b3 = binaryData[dataIndex++]; l = (byte) (b2 & 0x0f); k = (byte) (b1 & 0x03); byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2): (byte) ((b1) >> 2 ^ 0xc0); byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4): (byte) ((b2) >> 4 ^ 0xf0); byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6): (byte) ((b3) >> 6 ^ 0xfc); encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3]; encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f]; }// form integral number of 6-bit groups if (fewerThan24bits == EIGHTBIT) {b1 = binaryData[dataIndex]; k = (byte) (b1 & 0x03); byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2): (byte) ((b1) >> 2 ^ 0xc0); encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4]; encodedData[encodedIndex++] = PAD; encodedData[encodedIndex++] = PAD; } else if (fewerThan24bits == SIXTEENBIT) {b1 = binaryData[dataIndex]; b2 = binaryData[dataIndex + 1]; l = (byte) (b2 & 0x0f); k = (byte) (b1 & 0x03); byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2): (byte) ((b1) >> 2 ^ 0xc0); byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4): (byte) ((b2) >> 4 ^ 0xf0); encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2]; encodedData[encodedIndex++] = PAD; }return new String(encodedData); }/** * Decodes Base64 data into octects * * @param encoded * string containing Base64 data * @return Array containind decoded data. */ public static byte[] decode(String encoded) {if (encoded == null) {return null; }char[] base64Data = encoded.toCharArray(); // remove white spaces int len = removeWhiteSpace(base64Data); if (len % FOURBYTE != 0) {return null;// should be divisible by four }int numberQuadruple = (len / FOURBYTE); if (numberQuadruple == 0) {return new byte[0]; }byte decodedData[] = null; byte b1 = 0, b2 = 0, b3 = 0, b4 = 0; char d1 = 0, d2 = 0, d3 = 0, d4 = 0; int i = 0; int encodedIndex = 0; int dataIndex = 0; decodedData = new byte[(numberQuadruple) * 3]; for (; i < numberQuadruple - 1; i++) {if (!isData((d1 = base64Data[dataIndex++]))|| !isData((d2 = base64Data[dataIndex++]))|| !isData((d3 = base64Data[dataIndex++]))|| !isData((d4 = base64Data[dataIndex++]))) {return null; }// if found "no data" just return null b1 = base64Alphabet[d1]; b2 = base64Alphabet[d2]; b3 = base64Alphabet[d3]; b4 = base64Alphabet[d4]; decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); }if (!isData((d1 = base64Data[dataIndex++]))|| !isData((d2 = base64Data[dataIndex++]))) {return null;// if found "no data" just return null }b1 = base64Alphabet[d1]; b2 = base64Alphabet[d2]; d3 = base64Data[dataIndex++]; d4 = base64Data[dataIndex++]; if (!isData((d3)) || !isData((d4))) {// Check if they are PAD characters if (isPad(d3) && isPad(d4)) {if ((b2 & 0xf) != 0)// last 4 bits should be zero {return null; }byte[] tmp = new byte[i * 3 + 1]; System.arraycopy(decodedData, 0, tmp, 0, i * 3); tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); return tmp; } else if (!isPad(d3) && isPad(d4)) {b3 = base64Alphabet[d3]; if ((b3 & 0x3) != 0)// last 2 bits should be zero {return null; }byte[] tmp = new byte[i * 3 + 2]; System.arraycopy(decodedData, 0, tmp, 0, i * 3); tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); return tmp; } else {return null; }} else { // No PAD e.g 3cQl b3 = base64Alphabet[d3]; b4 = base64Alphabet[d4]; decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); }return decodedData; }/** * remove WhiteSpace from MIME containing encoded Base64 data. * * @param data * the byte array of base64 data (with WS) * @return the new length */ private static int removeWhiteSpace(char[] data) {if (data == null) {return 0; }// count characters that's not whitespace int newSize = 0; int len = data.length; for (int i = 0; i < len; i++) {if (!isWhiteSpace(data[i])) {data[newSize++] = data[i]; }}return newSize; } }
支付界面代码
package com.alipay.sdk.pay.demo; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.DialogInterface; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v4.app.FragmentActivity; import android.text.TextUtils; import android.view.View; import android.widget.Toast; import com.alipay.sdk.app.PayTask; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.Random; public class PayDemoActivity extends FragmentActivity {// 商户PID public static final String PARTNER = PayKeys.DEFAULT_PARTNER; // 商户收款账号 public static final String SELLER = PayKeys.DEFAULT_SELLER; // 商户私钥,pkcs8格式 public static final String RSA_PRIVATE = PayKeys.PRIVATE; // 支付宝公钥 public static final String RSA_PUBLIC = ""; private static final int SDK_PAY_FLAG = 1; @SuppressLint("HandlerLeak")private Handler mHandler = new Handler() {@SuppressWarnings("unused")public void handleMessage(Message msg) {switch (msg.what) {case SDK_PAY_FLAG: {PayResult payResult = new PayResult((String) msg.obj); /** * 同步返回的结果必须放置到服务端进行验证(验证的规则请看https://doc.open.alipay.com/doc2/ * detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665& * docType=1) 建议商户依赖异步通知 */ String resultInfo = payResult.getResult();// 同步返回需要验证的信息 String resultStatus = payResult.getResultStatus(); // 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档 if (TextUtils.equals(resultStatus, "9000")) {Toast.makeText(PayDemoActivity.this, "支付成功", Toast.LENGTH_SHORT).show(); } else {// 判断resultStatus 为非"9000"则代表可能支付失败 // "8000"代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态) if (TextUtils.equals(resultStatus, "8000")) {Toast.makeText(PayDemoActivity.this, "支付结果确认中", Toast.LENGTH_SHORT).show(); } else {// 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误 Toast.makeText(PayDemoActivity.this, "支付失败", Toast.LENGTH_SHORT).show(); }}break; }default:break; }}; }; @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); setContentView(R.layout.pay_main); }/** * call alipay sdk pay. 调用SDK支付 * */ public void pay(View v) {if (TextUtils.isEmpty(PARTNER) || TextUtils.isEmpty(RSA_PRIVATE) || TextUtils.isEmpty(SELLER)) {new AlertDialog.Builder(this).setTitle("警告").setMessage("需要配置PARTNER | RSA_PRIVATE| SELLER").setPositiveButton("确定", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialoginterface, int i) {// finish(); }}).show(); return; }String orderInfo = getOrderInfo("测试的商品", "该测试商品的详细描述", "0.01"); /** // * 特别注意,这里的签名逻辑需要放在服务端,切勿将私钥泄露在代码中! // */ String sign = sign(orderInfo); try {/** * 仅需对sign 做URL编码 */ sign = URLEncoder.encode(sign, "UTF-8"); } catch (UnsupportedEncodingException e) {e.printStackTrace(); }/** * 完整的符合支付宝参数规范的订单信息 */ final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType(); Runnable payRunnable = new Runnable() {@Override public void run() {// 构造PayTask 对象 PayTask alipay = new PayTask(PayDemoActivity.this); // 调用支付接口,获取支付结果 String result = alipay.pay(payInfo, true); Message msg = new Message(); msg.what = SDK_PAY_FLAG; msg.obj = result; mHandler.sendMessage(msg); }}; // 必须异步调用 Thread payThread = new Thread(payRunnable); payThread.start(); }/** * get the sdk version. 获取SDK版本号 * */ public void getSDKVersion() {PayTask payTask = new PayTask(this); String version = payTask.getVersion(); Toast.makeText(this, version, Toast.LENGTH_SHORT).show(); }/** * 原生的H5(手机网页版支付切natvie支付) 【对应页面网页支付按钮】 * * @param v */ public void h5Pay(View v) {// Intent intent = new Intent(this, H5PayDemoActivity.class); Bundle extras = new Bundle(); /** * url是测试的网站,在app内部打开页面是基于webview打开的,demo中的webview是H5PayDemoActivity, * demo中拦截url进行支付的逻辑是在H5PayDemoActivity中shouldOverrideUrlLoading方法实现, * 商户可以根据自己的需求来实现 */ String url = "http://m.meituan.com"; // url可以是一号店或者美团等第三方的购物wap站点,在该网站的支付过程中,支付宝sdk完成拦截支付 extras.putString("url", url); // intent.putExtras(extras); // startActivity(intent); }/** * create the order info. 创建订单信息 * */ private String getOrderInfo(String subject, String body, String price) {// 签约合作者身份ID String orderInfo = "partner=" + "\"" + PARTNER + "\""; // 签约卖家支付宝账号 orderInfo += "&seller_id=" + "\"" + SELLER + "\""; // 商户网站唯一订单号 orderInfo += "&out_trade_no=" + "\"" + getOutTradeNo() + "\""; // 商品名称 orderInfo += "&subject=" + "\"" + subject + "\""; // 商品详情 orderInfo += "&body=" + "\"" + body + "\""; // 商品金额 orderInfo += "&total_fee=" + "\"" + price + "\""; // 自己服务器的信号 orderInfo += "&trade_status=" + "\"" + "TRADE_SUCCESS" + "\""; // 服务器异步通知页面路径 orderInfo += "¬ify_url=" + "\"" + "http://yuanguu.com:8082/views/notify_url.do" + "\""; // 服务接口名称, 固定值 orderInfo += "&service=\"mobile.securitypay.pay\""; // 支付类型, 固定值 orderInfo += "&payment_type=\"1\""; // 参数编码, 固定值 orderInfo += "&_input_charset=\"utf-8\""; // 设置未付款交易的超时时间 // 默认30分钟,一旦超时,该笔交易就会自动被关闭。 // 取值范围:1m~15d。 // m-分钟,h-小时,d-天,1c-当天(无论交易何时创建,都在0点关闭)。 // 该参数数值不接受小数点,如1.5h,可转换为90m。 orderInfo += "&it_b_pay=\"30m\""; // extern_token为经过快登授权获取到的alipay_open_id,带上此参数用户将使用授权的账户进行支付 // orderInfo += "&extern_token=" + "\"" + extern_token + "\""; // 支付宝处理完请求后,当前页面跳转到商户指定页面的路径,可空 orderInfo += "&return_url=\"m.alipay.com\""; // 调用银行卡支付,需配置此参数,参与签名, 固定值 (需要签约《无线银行卡快捷支付》才能使用) // orderInfo += "&paymethod=\"expressGateway\""; return orderInfo; }/** * get the out_trade_no for an order. 生成商户订单号,该值在商户端应保持唯一(可自定义格式规范) * */ private String getOutTradeNo() {SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault()); Date date = new Date(); String key = format.format(date); Random r = new Random(); key = key + r.nextInt(); key = key.substring(0, 15); return key; }/** * sign the order info. 对订单信息进行签名 * * @param content * 待签名订单信息 */ private String sign(String content) {return SignUtils.sign(content, RSA_PRIVATE); }/** * get the sign type we use. 获取签名方式 * */ private String getSignType() {return "sign_type=\"RSA\""; }}
直接复制代码就可运行
package com.alipay.sdk.pay.demo; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class ExternalFragment extends Fragment {@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {return inflater.inflate(R.layout.pay_external, container, false); } }
pay_external的布局
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" ><LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:gravity="center_vertical" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="10dp" android:text="商品名称:" android:textColor="#777777" tools:ignore="HardcodedText" /> <TextView android:id="@+id/product_subject" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="right" android:text="测试的商品" android:textColor="#333333" tools:ignore="HardcodedText" /> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:gravity="center_vertical" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="10dp" android:text="商品描述:" android:textColor="#777777" tools:ignore="HardcodedText" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="right" android:text="该测试商品的详细描述" android:textColor="#333333" tools:ignore="HardcodedText" /> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:gravity="center_vertical" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="10dp" android:text="商品价格:" android:textColor="#777777" tools:ignore="HardcodedText" /> <TextView android:id="@+id/product_price" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="right" android:text="0.01元" android:textColor="#ff6600" tools:ignore="HardcodedText" /> </LinearLayout> <Button android:id="@+id/pay" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:onClick="pay" android:text="支付" tools:ignore="HardcodedText" /> <!-- <Button android:id="@+id/h5pay" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:onClick="h5Pay" android:text="网页支付转native" tools:ignore="HardcodedText" />--> </LinearLayout> </ScrollView>
pay_main的布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ImageView android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/msp_demo_title_bg" android:scaleType="center" android:src="@drawable/msp_demo_title" tools:ignore="ContentDescription" /> <fragment android:id="@+id/fragment" android:name="com.alipay.sdk.pay.demo.ExternalFragment" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
Base64加密
package com.alipay.sdk.pay.demo; import android.text.TextUtils; public class PayResult {private String resultStatus; private String result; private String memo; public PayResult(String rawResult) {if (TextUtils.isEmpty(rawResult))return; String[] resultParams = rawResult.split(";"); for (String resultParam : resultParams) {if (resultParam.startsWith("resultStatus")) {resultStatus = gatValue(resultParam, "resultStatus"); }if (resultParam.startsWith("result")) {result = gatValue(resultParam, "result"); }if (resultParam.startsWith("memo")) {memo = gatValue(resultParam, "memo"); }}}@Override public String toString() {return "resultStatus={" + resultStatus + "};memo={" + memo + "};result={" + result + "}"; }private String gatValue(String content, String key) {String prefix = key + "={"; return content.substring(content.indexOf(prefix) + prefix.length(), content.lastIndexOf("}")); }/** * @return the resultStatus */ public String getResultStatus() {return resultStatus; }/** * @return the memo */ public String getMemo() {return memo; }/** * @return the result */ public String getResult() {return result; } }
package com.alipay.sdk.pay.demo; import java.security.KeyFactory;import java.security.PrivateKey;import java.security.spec.PKCS8EncodedKeySpec; public class SignUtils { private static final String ALGORITHM = "RSA"; private static final String SIGN_ALGORITHMS = "SHA1WithRSA"; private static final String DEFAULT_CHARSET = "UTF-8"; public static String sign(String content, String privateKey) { try { PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec( Base64.decode(privateKey)); KeyFactory keyf = KeyFactory.getInstance(ALGORITHM); PrivateKey priKey = keyf.generatePrivate(priPKCS8); java.security.Signature signature = java.security.Signature .getInstance(SIGN_ALGORITHMS); signature.initSign(priKey); signature.update(content.getBytes(DEFAULT_CHARSET)); byte[] signed = signature.sign(); return Base64.encode(signed); } catch (Exception e) { e.printStackTrace(); } return null; } }
微信支付与支付宝支付相关推荐
- 个人开发者微信支付和支付宝支付
个人开发者是不能申请微信支付和支付宝支付的 很多第三方使用添加二维码监听转账操作来实现是否功能
- 腾腾流氓,云云更流氓(问微信怎样接入支付宝支付),手贱的赶紧点,你会感谢我的...
草原上的两匹马! 打从当年微信开始布局公众号之初时,估计就已经想到了与支付宝正面冲突的场面,所以微信先来个瞒天过海,在春晚搞了个微信红包,那叫一个火呀,此时的云云隐隐感觉到些许不安. 早期的微信开发者 ...
- 个人开发者只要一行代码接入微信支付和支付宝支付
接入支付功能 对于个人开发者来说,我们很希望我们开发的App被广泛使用,同时可以获得一些额外收入,那就更好了.但是在微信开放平台或者支付宝开放平台申请支付功能,需要是企业才可以接入,对于我们个人开 ...
- 微信支付及支付宝支付开发指南
从开始学习android开始到现在还没搞过三方支付,感觉挺遗憾的.看到最近有几篇关于微信支付和支付宝支付的文章,稍微进行一下整合,供大家参考. ---------------------------- ...
- 微信支付和支付宝支付整合(含设计模式1)
微信支付和支付宝支付整合(含设计模式1) 1.说明: 设计模式:单例+策略模式+抽象 在开发中经常对接微信支付和支付宝支付,相对来说,阿里的文档比微信的接口文档清晰一点,这里用的第三方库(com.gi ...
- 关于微信支付,支付宝支付
关于微信支付,支付宝支付 微信支付和支付宝支付属于第三方支付. 第三方支付是指具备一定实力和信誉保障的独立机构,通过与网联对接而促成交易双方进行交易的网络支付模式. 在第三方支付模式,买方选购商品后, ...
- iOS 微信支付和支付宝支付
1.微信支付 1)准备 通过cocoapods安装: #微信支付 pod 'WechatOpenSDK', '~> 1.8.1' 在微信开放平台注册应用,获取APPKey 在plist文件中添加 ...
- php做微信支付和支付宝支付的方法
php做微信支付和支付宝支付的方法 直接去官方下载demo 然后证书换一下 appid换下 就好了 如果测试成功 直接复制到项目中即可 这个方法目前是最好 最稳定的方法 查看原文:http://new ...
- 微信支付,支付宝支付,银联支付——三大支付总结
银联支付,支付宝支付,微信支付的三大总结,之前也有写过两篇. 微信支付,支付宝支付,银联支付--三大支付总结: http://blog.csdn.net/androidstarjack/article ...
- Magento支付宝手机网站支付插件V6.0旗舰版发布,支持在微信中使用支付宝支付,订单重新支付功能!...
2019独角兽企业重金招聘Python工程师标准>>> 功能 严格按照支付宝接口文档编写代码. 支付宝异步通知机制,确保订单状态及时更新,无丢失遗漏. 订单完美对接:支付后即使关掉支 ...
最新文章
- 值得关注!一种新型脑机接口--集成光子芯片的脑机接口是否可行?
- 为什么hbase里没有表会显示表已经存在_0712-6.2.0-HBase快照异常
- winpython anaconda_Windows:安装 Anaconda《 Python:基础 》
- android 内存分析工具_Android Camera内存问题剖析
- C语言实例:三个数从小到大排序
- 谷歌邮箱lmap服务器填什么_Gmail IMAP的应用技巧
- 手机兼职做任务发布悬赏赚钱的APP汇总到底有多少?
- ios学习之模仿韩寒one.一个UI
- 手机+测试网络+苹果手机软件,iOS-用手机网络测试Ipv6
- php退款,PHP实现微信申请退款流程的方法
- 数据挖掘简介及学习路径介绍
- 皮尔森相关性系数的计算python代码(一)
- 爬FH... ... 爽!
- 目标定位和检测系列中IOU的含义
- 百亿外卖CPS市场该怎么玩?(附公众号小程序裂变源码及搭建教程)
- 方向比努力重要,能力比知识重要,健康比成绩重要,生活比文凭重要,情商比智商重要
- PYTHON第二次实验
- 组合模式实例与解析 实例一:水果盘
- 【Qualcomm高通音频】如何使用QXDM、QCAT音频数据抓取
- 滴答清单(ticktick) 网页版api-2
热门文章
- python openslide 查看并保存切片的略缩图,并将Image图片转换成Base64
- 根据GPS数据的经纬度取天气预报和地名
- 莫比乌斯:百度凤巢下一代广告召回系统
- InstallShield 2008 And 脚本(十)
- php curl exec 返回值,php curl_exec()函数 CURL获取返回值的方法
- Qbao Network携手FinCredit Protocol启动大规模空投
- 带一张阿拉旅游卡,随时出发
- python使用matplotlib绘制饼状图
- 什么是危机公关与舆情监测?
- Firebird数据库及工具