欢迎留言、转发
文章首发地址:http://www.jianshu.com/p/febf7c2eea82
微信极速开发系列文章(微信支付、授权获取用户信息等):点击这里
目录
1、注册账号、开发者认证
2、添加应用
3、申请微信支付
4、技术开发功能实现步骤介绍
5、代码实例
服务端源码地址:http://git.oschina.net/javen205/weixin_guide
客户端源码地址:https://github.com/Javen205/JPay
微信APP支付接入商户服务中心 官方介绍文档
1、注册账号、开发者认证
在开放平台直接注册,注册邮箱不能与微信其他的产品同号。
比较坑的是微信公众号中的支付(微信买单、刷卡、公众号支付、wap支付)以及微信app支付都需要进行微信认证而不是公用一个微信商户平台(需要交两次认证的费用)。
微信认证这个时间比较短(毕竟交了300大洋)一般一个工作日就会有人联系你核查公司的资料。
微信认证(开发者资质认证)通过之后就可以在开放平台添加应用了(这个需要审核),应用通过之后就可以申请微信支付了(也需要审核)
2、添加应用
这个比较简单,按照提示操作就行 上图
应用包名只定义,应用签名可以使用资源下载中心的签名生成工具。务必记住包名以及签名keystore文件的密码,如果包名或者签名文件不对打包是唤不起微信支付的。
3、申请微信支付
如果添加的应用审核通过了(一个工作日),就可以直接申请微信支付了(7个工作日之内)。
审核通过之后将会收到审核通过的邮件,里面有登录商户平台的登录账户、密码、商户号以及一些操作指引的说明。服务端生成预付订单的签名需要密钥 设置方法可以参考这里
4、技术开发功能实现
微信APP支付介绍【文档】
APP端开发步骤说明 【文档】
这里主要聊聊Android微信支付,主要包括以下几个步骤
1、商户服务端生成订单并在微信平台生成预付订单
2、客户端调起微信支付进行支付
3、客户端回调支付结果
4、服务端接收支付通知
1、商户服务端生成订单并在微信平台生成预付订单
调起微信支付前需要服务器生成支付订单再调用【统一下单API】生成预付订单prepayId,再生成签名sign【调起支付API】
以上两个步骤建议都在服务端完成,客户端(android)通过接口获取对应的参数即可
2、客户端调起微信支付进行支付
通过微信提供的jar 唤起微信支付
3、客户端回调支付结果
参照微信SDK Sample,在net.sourceforge.simcpux.wxapi包路径中实现WXPayEntryActivity类【包名或类名不一致会造成无法回调】
栗子说明:认真反复读了几遍,感觉这句话有歧义是一个坑,测试的时候一直不回调。这里他想说的意识如下:
比如你申请应用包名为:javen.com
那么回调的WXPayEntryActivity
类必须放到javen.com.wxapi
的包下面
4、服务端接收支付通知
支付结果通知【官方文档】
代码实现参考开源项目 【点击这里】
5、代码实例
服务端代码:根据商户订单生成微信预付订单并返回唤起微信支付需要的参数。Demo中参数写成固定了仅供参考
此项目已开源 【点击这里】 如果对你有帮助请点击Start
告诉我 hahaha 。以下代码对应的目录在com.javen.weixin.controller.WeixinPayController.Java
中
public void appPay(){
//不用设置授权目录域名
//统一下单地址 https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1#
Map<String, String> params = new HashMap<String, String>()
params.put("appid", appid)
params.put("mch_id", partner)
params.put("nonce_str", System.currentTimeMillis() / 1000 + "")
params.put("body", "Javen微信公众号极速开发")
String out_trade_no=System.currentTimeMillis()+""
params.put("attach", "custom json")
params.put("out_trade_no", out_trade_no)
int price=10000
params.put("total_fee", price+"")
String ip = IpKit.getRealIp(getRequest())
if (StrKit.isBlank(ip)) {
ip = "127.0.0.1"
}
params.put("spbill_create_ip", ip)
params.put("notify_url", notify_url)
params.put("trade_type", "APP")
String sign = PaymentKit.createSign(params, paternerKey)
params.put("sign", sign)
String xmlResult = PaymentApi.pushOrder(params)
System.out.println(xmlResult)
Map<String, String> result = PaymentKit.xmlToMap(xmlResult)
String return_code = result.get("return_code")
String return_msg = result.get("return_msg")
if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
ajax.addError(return_msg)
renderJson(ajax)
return
}
String result_code = result.get("result_code")
if (StrKit.isBlank(result_code) || !"SUCCESS".equals(result_code)) {
ajax.addError(return_msg)
renderJson(ajax)
return
}
// 以下字段在return_code 和result_code都为SUCCESS的时候有返回
String prepay_id = result.get("prepay_id")
//封装调起微信支付的参数 https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12
Map<String, String> packageParams = new HashMap<String, String>()
packageParams.put("appid", appid)
packageParams.put("partnerid", partner)
packageParams.put("prepayid", prepay_id)
packageParams.put("package", "Sign=WXPay")
packageParams.put("noncestr", System.currentTimeMillis() + "")
packageParams.put("timestamp", System.currentTimeMillis() / 1000 + "")
String packageSign = PaymentKit.createSign(packageParams, paternerKey)
packageParams.put("sign", packageSign)
String jsonStr = JsonUtils.toJson(packageParams)
System.out.println("最新返回apk的参数:"+jsonStr)
renderJson(jsonStr)
}
- 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
- 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
客户端代码实现
使用单例模式统一入口,首先判断微信客户端是否安装,如果有安装再从商户服务器获取调起支付的参数
public class IPay {
private static IPay mIPay;
private Context mContext;
private IPay(Context context) {
mContext = context;
}
public static IPay getIntance(Context context){
if (mIPay == null) {
synchronized(IPay.class){
if (mIPay == null) {
mIPay = new IPay(context);
}
}
}
return mIPay;
}
public interface IPayListener{
void onPay(int code);
}
public void toTestPay(Order order,IPayListener listener){
if (order != null) {
if (IPayLogic.getIntance(mContext.getApplicationContext()).isWeixinAvilible()) {
Constants.payListener = listener;
new TestPayPrepay(mContext).execute();
}else {
Toast.makeText(mContext, "未安装微信", Toast.LENGTH_LONG).show();
}
}else {
Toast.makeText(mContext, "参数异常 order is null", Toast.LENGTH_LONG).show();
}
}
}
- 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
- 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
调起微信支付、获取调取微信支付参数、判断微信是否安装逻辑实现
public class IPayLogic {
private static IPayLogic mIPayLogic;
private Context mContext;
private IPayLogic(Context context) {
mContext = context;
}
public static IPayLogic getIntance(Context context){
if (mIPayLogic == null) {
synchronized(IPayLogic.class){
if (mIPayLogic == null) {
mIPayLogic = new IPayLogic(context);
}
}
}
return mIPayLogic;
}
public String testPay(){
return HttpKit.get(Constants.TESTPAY_URL);
}
/**
* 调起支付
* @param appId
* @param partnerId
* @param prepayId
* @param nonceStr
* @param timeStamp
* @param sign
*/
public void startWXPay(String appId,String partnerId,String prepayId,
String nonceStr,String timeStamp,String sign){
IWXAPI api= WXAPIFactory.createWXAPI(mContext, null);
api.registerApp(appId);
boolean isPaySupported = api.getWXAppSupportAPI() >= Build.PAY_SUPPORTED_SDK_INT;
if (!isPaySupported) {
Toast.makeText(mContext, "请更新微信客户端", Toast.LENGTH_SHORT).show();
return;
}
PayReq request = new PayReq();
request.appId = appId;
request.partnerId = partnerId;
request.prepayId= prepayId;
request.packageValue = "Sign=WXPay";
request.nonceStr=nonceStr;
request.timeStamp= timeStamp;
request.sign= sign;
api.sendReq(request);
}
/**
* 判断微信是否安装
* @param context
* @return
*/
public boolean isWeixinAvilible() {
final PackageManager packageManager = mContext.getPackageManager();
List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
if (pinfo != null) {
for (int i = 0; i < pinfo.size(); i++) {
String pn = pinfo.get(i).packageName;
if (pn.equals("com.tencent.mm")) {
return true;
}
}
}
return false;
}
}
- 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
- 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
HttpKit MD5 工具类
/**
* HttpKit
*/
public class HttpKit {
private HttpKit() {}
/**
* https 域名校验
*/
private class TrustAnyHostnameVerifier implements HostnameVerifier {
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
/**
* https 证书管理
*/
private class TrustAnyTrustManager implements X509TrustManager {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
}
private static final String GET = "GET";
private static final String POST = "POST";
private static String CHARSET = "UTF-8";
private static final SSLSocketFactory sslSocketFactory = initSSLSocketFactory();
private static final TrustAnyHostnameVerifier trustAnyHostnameVerifier = new HttpKit().new TrustAnyHostnameVerifier();
private static SSLSocketFactory initSSLSocketFactory() {
try {
TrustManager[] tm = {new HttpKit().new TrustAnyTrustManager() };
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tm, new java.security.SecureRandom());
return sslContext.getSocketFactory();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void setCharSet(String charSet) {
if (charSet.isEmpty()) {
throw new IllegalArgumentException("charSet can not be blank.");
}
HttpKit.CHARSET = charSet;
}
private static HttpURLConnection getHttpConnection(String url, String method, Map<String, String> headers) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException {
URL _url = new URL(url);
HttpURLConnection conn = (HttpURLConnection)_url.openConnection();
if (conn instanceof HttpsURLConnection) {
((HttpsURLConnection)conn).setSSLSocketFactory(sslSocketFactory);
((HttpsURLConnection)conn).setHostnameVerifier(trustAnyHostnameVerifier);
}
conn.setRequestMethod(method);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setConnectTimeout(19000);
conn.setReadTimeout(19000);
conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36");
if (headers != null && !headers.isEmpty())
for (Entry<String, String> entry : headers.entrySet())
conn.setRequestProperty(entry.getKey(), entry.getValue());
return conn;
}
/**
* Send GET request
*/
public static String get(String url, Map<String, String> queryParas, Map<String, String> headers) {
HttpURLConnection conn = null;
try {
conn = getHttpConnection(buildUrlWithQueryString(url, queryParas), GET, headers);
conn.connect();
return readResponseString(conn);
}
catch (Exception e) {
throw new RuntimeException(e);
}
finally {
if (conn != null) {
conn.disconnect();
}
}
}
public static String get(String url, Map<String, String> queryParas) {
return get(url, queryParas, null);
}
public static String get(String url) {
return get(url, null, null);
}
/**
* Send POST request
*/
public static String post(String url, Map<String, String> queryParas, String data, Map<String, String> headers) {
HttpURLConnection conn = null;
try {
conn = getHttpConnection(buildUrlWithQueryString(url, queryParas), POST, headers);
conn.connect();
OutputStream out = conn.getOutputStream();
out.write(data.getBytes(CHARSET));
out.flush();
out.close();
return readResponseString(conn);
}
catch (Exception e) {
throw new RuntimeException(e);
}
finally {
if (conn != null) {
conn.disconnect();
}
}
}
public static String post(String url, Map<String, String> queryParas, String data) {
return post(url, queryParas, data, null);
}
public static String post(String url, String data, Map<String, String> headers) {
return post(url, null, data, headers);
}
public static String post(String url, String data) {
return post(url, null, data, null);
}
private static String readResponseString(HttpURLConnection conn) {
StringBuilder sb = new StringBuilder();
InputStream inputStream = null;
try {
inputStream = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, CHARSET));
String line = null;
while ((line = reader.readLine()) != null){
sb.append(line).append("\n");
}
return sb.toString();
}
catch (Exception e) {
throw new RuntimeException(e);
}
finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
}
}
}
}
/**
* Build queryString of the url
*/
private static String buildUrlWithQueryString(String url, Map<String, String> queryParas) {
if (queryParas == null || queryParas.isEmpty())
return url;
StringBuilder sb = new StringBuilder(url);
boolean isFirst;
if (url.indexOf("?") == -1) {
isFirst = true;
sb.append("?");
}
else {
isFirst = false;
}
for (Entry<String, String> entry : queryParas.entrySet()) {
if (isFirst) isFirst = false;
else sb.append("&");
String key = entry.getKey();
String value = entry.getValue();
if (!value.isEmpty())
try {value = URLEncoder.encode(value, CHARSET);} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}
sb.append(key).append("=").append(value);
}
return sb.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
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 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
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
public class MD5 {
public static String MD5sign(String s) {
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
try {
byte[] btInput = s.getBytes("UTF-8");
MessageDigest mdInst = MessageDigest.getInstance("MD5");
mdInst.update(btInput);
byte[] md = mdInst.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str).toLowerCase();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
System.out.println(MD5sign("Hello world"));
}
}
- 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
- 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
使用AsyncTask
异步获取调起微信支付的相关参数。当然你也可以使用其他的异步网络请求开源框架
public class TestPayPrepay extends AsyncTask<Object, Integer, String> {
private Context mContext;
public TestPayPrepay(Context context) {
this.mContext = context;
}
@Override
protected String doInBackground(Object... params) {
System.out.println("TestPayPrepay doInBackground");
return IPayLogic.getIntance(mContext).testPay();
}
@Override
protected void onPostExecute(String result) {
try {
if (result!=null) {
System.out.println("TestPayPrepay result>"+result);
JSONObject data = new JSONObject(result);
if(!data.has("code")){
String sign = data.getString("sign");
String timestamp = data.getString("timestamp");
String noncestr = data.getString("noncestr");
String partnerid = data.getString("partnerid");
String prepayid = data.getString("prepayid");
String appid = data.getString("appid");
Toast.makeText(mContext, "正在调起支付", Toast.LENGTH_SHORT).show();
Constants.APP_ID = appid;
IPayLogic.getIntance(mContext).startWXPay(appid, partnerid, prepayid, noncestr, timestamp, sign);
}else{
String message = data.getString("message");
Log.d("PAY_GET", "返回错误"+message);
Toast.makeText(mContext, "返回错误:"+message, Toast.LENGTH_SHORT).show();
}
}else {
System.out.println("get prepayid exception, is null");
}
} catch (Exception e) {
Log.e("PAY_GET", "异常:"+e.getMessage());
Toast.makeText(mContext, "异常:"+e.getMessage(), Toast.LENGTH_SHORT).show();
}
super.onPostExecute(result);
}
}
- 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
- 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
支付结果回调
<activity
android:name="[应用的包名].wxapi.WXPayEntryActivity"
android:exported="true"
android:theme="@android:style/Theme.Translucent"
android:launchMode="singleTop" >
</activity>
封装的是SDK 所以这里设置了一个透明的主题
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler{
private IWXAPI api;
private IPayListener payListener;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
LinearLayout ll = new LinearLayout(this);
setContentView(ll);
api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
api.handleIntent(getIntent(), this);
finish();
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
}
@Override
public void onReq(BaseReq req) {
}
@Override
public void onResp(BaseResp resp) {
payListener = Constants.payListener;
int code = resp.errCode;
System.out.println("onResp errCode>"+code);
if (payListener!=null) {
payListener.onPay(code);
System.out.println("payListener callback");
}else {
System.out.println("payListener not callback");
}
}
}
- 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
- 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
注意:如果回调的code
一直返回-1
1、请检查应用包名以及apk 的签名是否与你提交到微信开放平台的一致
2、请检查返回调取微信支付的参数是否正确
大部分原因是第一种
遗留问题:由于支付应用的包名不固定WXPayEntryActivity
无法封装到jar中,需要单独在支付应用添加.wxapi
这个包名并复制 WXPayEntryActivity
到此包中。如果有好的解决方案欢迎留言
微信开发系列文章 http://www.jianshu.com/p/a172a1b69fdd
推荐阅读
极速开发微信公众号之微信买单
极速开发微信公众号之公众号支付
极速开发微信公众号之扫码支付
极速开发微信公众号之刷卡支付
极速开发微信公众号之现金红包
极速开发微信公众号之模板消息
如果此文章对你有帮助请点击喜欢告诉我
服务端源码地址:http://git.oschina.net/javen205/weixin_guide
客户端源码地址:https://github.com/Javen205/JPay