最近做了谷歌后端充值效验,然后记录下遇到的问题。
首先就是要配置谷歌账户等,这个可以参考其他配置,我这边只是实现代码处理,后台创建那里,更多的还是我们运营处理的,我协助分析处理等,也没有记录流程。这里只说后端代码和遇到的问题。
创建账户可以参考下面文章:
Google内购 Java服务端(Springboot)校验订单详细流程_google内购服务端验证 java_zhifeng687的博客-优快云博客
Google pay java 后端验证方式二_java 谷歌支付_不求人Stone的博客-优快云博客
这个是谷歌自己的文档:
https://developers.google.com/android-publisher/getting_started?hl=zh-cn
功能是app内购商品,实现一次性购买。
一:通过上面的操作,你会发现有一个json文件,我们叫它 purchaseToken.json 吧,需要保存下来。
<!-- maven 主要 依赖库 -->
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-androidpublisher</artifactId>
<version>v3-rev20230615-2.0.0</version>
</dependency>
二:初始化谷歌SDK 代码如下:
public class GoogleSDK {
private static AndroidPublisher androidPublisher = null;
public GoogleSDK() {
try {
String applicationName = "应用名称";
InputStream purchaseToken = GoogleSDK.class.getClassLoader().getResourceAsStream("purchaseToken.json");
assert purchaseToken != null;
GoogleCredentials credentials = GoogleCredentials.fromStream(purchaseToken)
.createScoped(Sets.newHashSet(AndroidPublisherScopes.ANDROIDPUBLISHER));
androidPublisher = new AndroidPublisher.Builder(
GoogleNetHttpTransport.newTrustedTransport(),
GsonFactory.getDefaultInstance(),
new HttpCredentialsAdapter(credentials)).setApplicationName(applicationName).build();
} catch (GeneralSecurityException | IOException ex) {
logger.error("Google Channel Init Error!" + ex.getMessage());
return;
}
logger.info("Google Channel Init Success!");
}
}
三:订单消费是放在服务器处理的,前端处理会更复杂,所以放在了服务器处理。
private void consumeOrder(String token, String pname, String productId) throws IOException {
androidPublisher.purchases().products().consume(pname, productId, token).execute();
}
这里有个小插曲,刚开始用的 androidpublisher 版本,它没有 consume 方法进行消费,然后查这个问题查了一段时间,为什么官方文档(https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.products?hl=zh-cn#resource)存在方法,但是通过 api 调用却没有,询问 chatgpt 结果告诉我谷歌2018年后取消了consume方法,然后就离谱,和前端沟通下,前端反馈他们不好处理,然后我就想到,为什么文档有,但是api 没有呢,然后就想着是不是版本问题,就切换到最新版本,结果有了,chatgpt 不能全信啊(狗头)。
四:验证订单
private boolean verifyDeliver(long puid, long uid, String token, String pname, String productId) throws IOException {
final AndroidPublisher.Purchases.Products.Get request = androidPublisher.purchases().products()
.get(pname, productId, token);
final ProductPurchase purchase = request.execute();
// purchase 就能获取到官方文档的内容
}
验证完成。
总结遇到的问题,遇到的问题,才是最大的阻碍。
1. 初始化时遇到报错,ExceptionInInitializerError 是由GoogleUtils<init> 报错的。
定位到GoogleUtils 报错问题行 , 此处 VERSION 返回了 "unknown-version", 导致matcher时候无法通过 正则表达式获取,然后报错。
Matcher versionMatcher = VERSION_PATTERN.matcher(VERSION);
然后查看为什么返回了那个,下面是源代码:
InputStream inputStream = GoogleUtils.class.getResourceAsStream("google-api-client.properties");
try {
if (inputStream != null) {
Properties properties = new Properties();
properties.load(inputStream);
version = properties.getProperty("google-api-client.version");
}
}
以为文件 google-api-client.properties 不存在,然后去依赖里面找到了文件。然后就很懵,这些东西都有,为啥报错了呢,还在这一步。第一反应应该是环境的问题,然后想着应该环境没配置啥啊,检测依赖的 jar 包,发现是没有问题的,然后去机器上看到了,安装的java 里面一堆 jar 包,都是谷歌的,导致我这边获取版本错误,其实这里就是maven项目打包的jar包和本地机器jar包紊乱了,把本地jar包删掉了,就正常了。
2. consume 时候报错如下:
"code": 400,
"errors": [
{
"domain": "androidpublisher",
"message": "The product purchase is not owned by the user.",
"reason": "productNotOwnedByUser"
}
],
"message": "The product purchase is not owned by the user."
我是用测试订单卡,购买发货的,测试卡只能持续 5分钟的有效期,超过了就失效了,这种是测试时间失效了,正式卡有3天。所以测试时候,一定要购买完成,尽快测试。不然就出现上面的错误。