Android Google应用内支付

前言

之前写过了Facebook登录Google登录,那么Google支付能错过吗?当然是不能的了。今天来说说Google支付,我们这里只说集成方式,配置可以看Google(应用内支付)官方文档

准备工作

要集成Google支付的准备工作有哪些呢?

  • 1、手机上安装Google服务(当然是针对国内的用户,国外的相信大部分都有Google服务);

  • 2、一个绑定信用卡的Google账号;

  • 3、Google play客户端;

  • 4、Google play console用于配置应用内商品信息);

  • 5、科学上网的工具。

    首先

    上面的准备工作都做好了之后需要干什么呢?当然是在Google play console上配置相关应用和商品信息了,至于如何配置具体可以参考Google支付配置

  • 1、支付流程说明
    关于Google支付的流程说明:
    1>前提条件

    1、检查你的包名和签名文件是否和Google Console 上面上传的apk包是否一致
    2、检查版本号是否和Google console发布的apk版本是否一致
    3、检查你是否可以购买,是否绑定了银行卡,手机支不支持Google支付,手机是否有Google服务

    2>支付流程

    1、第一步,初始化Google支付
    2、第二步,初始化成功后调用查询购买的商品操作,查询成功调用消耗操作,防止不能购买的情 况发生
    3、第三步,生成订单号进行购买操作
    4、第四步,购买成功后再次调用一次消耗操作(为了下次购买可以成功)
    5、第五步,拿到Google支付返回的相关信息,在服务器进行验证操作。
    6、第六步,服务器拿到你上传的相关信息和Google支付进行交互验证,验证成功后Google发货,服务器给你返回相关信息
  • 2、集成工作
    首先在AndroidManifest文件中加入支付权限和版本

1
2
3
4
5
<uses-permission android:name="com.android.vending.BILLING"/>
//在application的节点下添加
<meta-data
android:name="com.google.android.gms.vision.DEPENDENCIES"
android:value="face" />

Google支付需要的文件

其次

Google支付管理类的创建(支付封装成一个工具类)

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
public class GooglePlayManager {

private static final String TAG = GooglePlayManager.class.getSimpleName();

@SuppressLint("StaticFieldLeak")
private static IabHelper mHelper;
//是否初始化
private static boolean mSetupDone = false;
//公钥
private static String mPublicKey;
//订单号
private static String payload;
//商品集合
private static List<String> mGoodsList = new ArrayList<>();

/**
* 初始化
*
* @param context 上下文
* @param publicKey 公钥
* @param productID 商品ID
* @param goodsList 商品集合
* @param mListener 接口
*/
public static void init(final Context context, String publicKey, final String productID,
final OnGoogleInitListener mListener) {
mPublicKey = publicKey;
//创建谷歌帮助类
mHelper = new IabHelper(context, publicKey);
mHelper.enableDebugLogging(true);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
@Override
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
mListener.onGoogleInitFailed(result.getMessage());
mSetupDone = false;
} else {
mSetupDone = true;
mListener.onGoogleInitSuccess("init Success");
//getLTOrderID(LTAppID, LTAppKey,gid, packageId, params);
try {
mHelper.queryInventoryAsync(true, null, null,
new IabHelper.QueryInventoryFinishedListener() {
@Override
public void onQueryInventoryFinished(IabResult result, Inventory inv) {
if (inv != null && inv.getAllPurchases() != null
&& inv.getAllPurchases().size() > 0) {
mGoodsList = getGoodsList(inv.getAllPurchases());
}
if (result != null && inv != null) {
if (result.isSuccess() && inv.getAllPurchases() != null
&& inv.getAllPurchases().size() > 0) {
//消费, 并下一步, 这里Demo里面我没做提示,将购买了,但是没消费
// 掉的商品直接消费掉, 正常应该
//给用户一个提示,存在未完成的支付订单,是否完成支付
for (int i = 0; i < inv.getAllPurchases().size(); i++) {
consumeProduct2(inv.getAllPurchases().get(i));
}

}
}
}
});
} catch (IabHelper.IabAsyncInProgressException e) {
e.printStackTrace();
}
}
}
});
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
}

/**
* 消费掉商品
*/
private static void consumeProduct(Purchase purchase) {
try {
mHelper.consumeAsync(purchase, new IabHelper.OnConsumeFinishedListener() {
@Override
public void onConsumeFinished(Purchase purchase, IabResult result) {

});
} catch (IabHelper.IabAsyncInProgressException e) {
e.printStackTrace();
}
}

/**
* 验证订单
*/
private static void consumeProduct2(Purchase purchase) {
try {
mHelper.consumeAsync(purchase, new IabHelper.OnConsumeFinishedListener() {
@Override
public void onConsumeFinished(Purchase purchase, IabResult result) {
if (purchase.getToken() != null && purchase.getDeveloperPayload() != null) {
//这里需要和你们的服务器进行商量然后选择上传什么参数进行上传验证
upload2server2(purchase.getToken(), purchase.getDeveloperPayload());
}

});
} catch (IabHelper.IabAsyncInProgressException e) {
e.printStackTrace();
}
}

/**
* 购买
*
* @param context 上下文
* @param requestCode 请求码
* @param goodsList 商品集合
* @param productID 商品ID
* @param mListener 接口
*/
public static void recharge(final Context context,final int requestCode,
final String productID,Map<String,Object>mParams,
final OnGooglePlayResultListener mListener) {
if (mSetupDone) {
if (判断是否登录成功) {
getLTOrderID(mParams);
}

} else {
if (TextUtils.isEmpty(mPublicKey)) {
//创建谷歌帮助类
mHelper = new IabHelper(context, mPublicKey);
mHelper.enableDebugLogging(true);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
@Override
public void onIabSetupFinished(IabResult result) {
if (result.isFailure()) {
mSetupDone = false;
}
if (result.isSuccess()) {
mSetupDone = true;
}
}
});
}

}
}

接口回调成功走下面的步骤

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
/**
*
*创建订单
*/
private void getLTOrderID(Map<String,Object>mParams){
...
...
...
if(success){//省略号那里写自己创建订单的接口回调

try {
if (mHelper == null) return;
List<String> subSku = new ArrayList<>();
mHelper.queryInventoryAsync(true, goodsList, subSku,
new IabHelper.QueryInventoryFinishedListener() {
@Override
public void onQueryInventoryFinished(IabResult result, Inventory inv) {
if (result != null) {
if (result.isSuccess() && inv.hasPurchase(productID)) {
//消费, 并下一步, 这里Demo里面我没做提示,将购买了,但是没消费掉的商
//品直接消费掉, 正常应该
//给用户一个提示,存在未完成的支付订单,是否完成支付
consumeProduct(inv.getPurchase(productID));
} else {
getProduct((Activity) context, requestCode, productID);
}
}
}
}

});
} catch (IabHelper.IabAsyncInProgressException e) {
e.printStackTrace();
}
}

}


/**
* 产品获取
*
* @param context 上下文
* @param REQUEST_CODE 请求码
* @param SKU 产品唯一id, 填写你自己添加的商品id
* @param mListener 回调监听
*/
private static void getProduct(final Activity context, int REQUEST_CODE,
final String SKU, final OnGooglePlayResultListener mListener) {
if (!TextUtils.isEmpty(payload)) {
try {
mHelper.launchPurchaseFlow(context, SKU, REQUEST_CODE, new IabHelper.OnIabPurchaseFinishedListener() {
@Override
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
if (result.isFailure()) {
mListener.onPlayError(result.getMessage());
return;
}
mListener.onPlaySuccess("Purchase successful");
if (purchase.getSku().equals(SKU)) {
//购买成功,调用消耗
consumeProduct(purchase);
}
}
}, payload);
} catch (IabHelper.IabAsyncInProgressException e) {
e.printStackTrace();
}
} else {
mListener.onPlayError("Order creation failed");
}
}

/**
* 回调
*
*
* @param requestCode 请求码
* @param resultCode 结果码
* @param data 数据

*/
public static void onActivityResult( int requestCode, int resultCode, Intent data, int selfRequestCode) {
//将回调交给帮助类来处理, 否则会出现支付正在进行的错误
if (mHelper == null) return;
mHelper.handleActivityResult(requestCode, resultCode, data);
if (requestCode == selfRequestCode) {
int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
//订单信息
String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
if (!TextUtils.isEmpty(purchaseData)) {
GoogleModel googleModel = new Gson().fromJson(purchaseData, GoogleModel.class);
Log.e(TAG, googleModel.getPurchaseToken());
Map<String, Object> params = new WeakHashMap<>();
params.put(购买成功的token(具体以自己服务的规定为准), googleModel.getPurchaseToken());
params.put(订单号, payload);
//上传到服务器进行验证之后再次调用消费用于消耗掉购买的商品
upload2server(xx);

}
}

}
/**
*上传到服务器验证
*/
public void upload2server(xx xx){

}
/**
*上传到服务器验证
*/
public void upload2server2(xx xx){
...
...
...
//验证成功后再次调用购买方法
recharge(final Context context,final int requestCode,
final String productID,Map<String,Object>mParams,
final OnGooglePlayResultListener mListener)
}

/**
* 释放资源
*/
public static void release() {
if (mHelper != null) {
mHelper.disposeWhenFinished();
}
mHelper = null;
}
/**
* 获取商品集合
*/
private static List<String> getGoodsList(
List<Purchase> mList) {
mGoodsList = new ArrayList<>();
for (int i = 0; i < mList.size(); i++) {
mGoodsList.add(mList.get(i).getSku());
}
return mGoodsList;
}
}

流程说明:首先初始化Google支付,初始化成功后查询是否有未消费的,如果有则消费,如果没有则继续调用购买功能。当然,购买之前需要创建订单,之后传入Google支付需要的参数支付。支付成功后在onActivityResult方法里获取到Google返回的token,然后到自己的服务器做验证。验证成功后再次调用Google的消费功能,用于消耗此次购买。这一步千万不能省,要不下次可能就不能进行购买了。

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
public class GoogleModel {

private String packageName;
private String productId;
private long purchaseTime;
private int purchaseState;
private String developerPayload;
private String purchaseToken;

public String getOrderId() {
return orderId;
}

public void setOrderId(String orderId) {
this.orderId = orderId;
}

public String getPackageName() {
return packageName;
}

public void setPackageName(String packageName) {
this.packageName = packageName;
}

public String getProductId() {
return productId;
}

public void setProductId(String productId) {
this.productId = productId;
}

public long getPurchaseTime() {
return purchaseTime;
}

public void setPurchaseTime(long purchaseTime) {
this.purchaseTime = purchaseTime;
}

public int getPurchaseState() {
return purchaseState;
}

public void setPurchaseState(int purchaseState) {
this.purchaseState = purchaseState;
}

public String getDeveloperPayload() {
return developerPayload;
}

public void setDeveloperPayload(String developerPayload) {
this.developerPayload = developerPayload;
}

public String getPurchaseToken() {
return purchaseToken;
}

public void setPurchaseToken(String purchaseToken) {
this.purchaseToken = purchaseToken;
}
}
  • 接口
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
/**
*初始化接口
*/
public interface OnGoogleInitListener {
/**
* 初始化成功
*
* @param success 成功回调信息
*/
void onGoogleInitSuccess(String success);

/**
* 初始化失败回调
*
* @param result 失败回调信息
*/
void onGoogleInitFailed(String result);
}

/**
*支付结果接口
*/
public interface OnGoogleResultListener {
/**
* Google play 返回信息(成功)
*
* @param result 成功信息
*/
void onResultSuccess(String result);

/**
* 上传到服务器错误
*
* @param ex 错误信息
*/
void onResultError(Throwable ex);

/**
* Google play 返回信息(失败)
*
* @param failedMsg 失败内容
*/
void onResultFailed(String failedMsg);
}
/**
*创建订单接口
*/
public interface OnCreateOrderListener {

void onOrderSuccess(String result);

void onOrderFailed(Throwable ex);

void onOrderError(String error);
}
/**
*上传到服务器结果接口
*/
public interface OnGoogleResultListener {
/**
* Google play 返回信息(成功)
*
* @param result 成功信息
*/
void onResultSuccess(String result);

/**
* 上传到服务器错误
*
* @param ex 错误信息
*/
void onResultError(Throwable ex);

/**
* Google play 返回信息(失败)
*
* @param failedMsg 失败内容
*/
void onResultFailed(String failedMsg);
}

最后

好了,这就是今天的Google支付说明了,写的不好还请谅解。

感谢

谷歌支付验证 403错误