XiaoCongGame / sdk-smart-lib

The Android library project for Xiaocong SDK
0 stars 1 forks source link

SDK: Unable to purchase, PaymentResponse parsing error. #11

Closed thedmd closed 10 years ago

thedmd commented 10 years ago

After trying to purchase there is an exception in parsing server response.

15:07:12.124    接口    Error   18541   {"head":{"server":"Nexus 7#nakasi#grouper#","method":"payment","version":"3.3","hardware":"30:85:A9:2F:BF:05"},"body":{"sign":"304ca84a8761cfa0feb6cca27f679ae4","amount":"1500","pkgName":"com.artifexmundi.clockworktales.android.xiaocong.free","orderNo":"100028100000000000000000000003","signType":"md5","partnerId":"100028","mark":"Some remark","goodsDes":"Unlock game"}}
15:07:13.014    Payment     Error   18541   {"message":"order number has exists","status":510}
15:07:13.024    PaymentActivity Error   18541   org.json.JSONException: No value for data
15:07:13.024    PaymentActivity Error   18541           at org.json.JSONObject.get(JSONObject.java:354)
15:07:13.024    PaymentActivity Error   18541           at org.json.JSONObject.getJSONObject(JSONObject.java:569)
15:07:13.024    PaymentActivity Error   18541           at com.xiaocong.xcobject.PaymentResponse.formJson(PaymentResponse.java:25)
15:07:13.024    PaymentActivity Error   18541           at com.xiaocong.xcapi.XCAPI.doPayment(XCAPI.java:64)
15:07:13.024    PaymentActivity Error   18541           at com.xiaocong.sdk.pay.PaymentActivity.prepareOrderInServer(PaymentActivity.java:262)
15:07:13.024    PaymentActivity Error   18541           at com.xiaocong.sdk.pay.PaymentActivity_.access$6(PaymentActivity_.java:1)
15:07:13.024    PaymentActivity Error   18541           at com.xiaocong.sdk.pay.PaymentActivity_$7.execute(PaymentActivity_.java:187)
15:07:13.024    PaymentActivity Error   18541           at org.androidannotations.api.BackgroundExecutor$Task.run(BackgroundExecutor.java:302)
15:07:13.024    PaymentActivity Error   18541           at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:390)
15:07:13.024    PaymentActivity Error   18541           at java.util.concurrent.FutureTask.run(FutureTask.java:234)
15:07:13.024    PaymentActivity Error   18541           at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:153)
15:07:13.024    PaymentActivity Error   18541           at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:267)
15:07:13.024    PaymentActivity Error   18541           at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
15:07:13.024    PaymentActivity Error   18541           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
15:07:13.024    PaymentActivity Error   18541           at java.lang.Thread.run(Thread.java:856)
ReDreamport commented 10 years ago

I found a order '100028100000000000000000000003' in our system so the response of our server was correct This might come from your previous tests. I added a explicit result code com.xiaocong.sdk.PaymentResults.DUPLICATE_ORDER_NO for this case. If you got this error, please try with other order no.

Your pkgName seems changing to com.artifexmundi.clockworktales.android.xiaocong.free. Please note that some configurations depend on and vary with your pkgName. So please let me know if you check that.

thedmd commented 10 years ago

How SDK behave if I start an purchase with specific order no and purchase fail or beeing cancelled? Is this order no toasted and I cannot resume payment?

com.artifexmundi.clockworktales.android.xiaocong.free is final package name.

ReDreamport commented 10 years ago

We treat order no you send as an unique identifier of a transaction. So whatever the result, you should not use it again. If you get fail, increase the order no and try another payment please.

thedmd commented 10 years ago

Is there any user ID I could use to vary Order No? There is restore purchase button in game and I should be able to generate same Order No for user who already bought product on his account.

ReDreamport commented 10 years ago

What does 'restore button' mean:

  1. Restore a failed purchase?
  2. (Buy again actually) Buy a item bought before for second time? And you don't wan to the payment activity shown up again. You expect the payment will be done in background? If you mean so, the SDK don't support this schema now.
thedmd commented 10 years ago

Restore purchase is used to restore transaction user made earlier. Consider scenario: install game, purchase, uninstall game, install game, restore purchase. If Order No will be generated based on time stamp it will not be possible to determine which was used to purchase product in the first place.

However if such functionality is not desired we just disable it.

Ad 1. No, I thought there there was a way to retry failed transaction. Apparently I was wrong.

ReDreamport commented 10 years ago

I think it's 'restore purchased items', not 'restore the payments'. I know after uninstall the app, app data will be erased. So I think the items that users had purchased should be stored in you server, such as in UserAssets :) . After re-install the app, the data in your server is the only trusted data used to restore user progress.

By the way, there're not robust way to identify a user/device in Android, I think. Not andorid device id, not MAC address. And in TVs, there's no SIM card! SO, I think you could not RESTORE user data in a robust way. Help me if you know better way, thanks~

Please also note that not every payment order binds to a user id. For some payment ways, user could pay without signing in Xiaocong Account.

I don't think order no based on timestamp works well in a distributed environment. The demo is just a demo. I think you'd better generate a unique order no in your server, globally. Bind the order no to a identifier used in your app(if you want to restore). Then you could restore user data.

thedmd commented 10 years ago

Thank you for clarification.

Payment way is selected after calling PaymentHelper.startMe() function and I see no way to determine if signing to Xiaocong Account is required or not. So I always prompt for login before purchase.

ReDreamport commented 10 years ago

Then, you could bind the user identifier to you order no.

You might need this API: tv.xiaocong.sdk.XcServiceClient.getUserBasicInfo(accessToken). It return a UserBasicInfo instance. UserBasicInfo.id is the user identifier.

Please note that user is able to change the Xiaocong Account that used to pay. So the account that finish the order may be not the account that login before.

thedmd commented 10 years ago

Thank you for an API hint.

Before invoking purchase we give user a chance to change account. I didn't notice any way of changing it after calling startMe() on PaymentHelper. Is there one?

ReDreamport commented 10 years ago

Please refer to https://github.com/XiaoCongGame/sdk-smart-lib/blob/master/doc/english/payment.guide.md#xiaocong-coins.

thedmd commented 10 years ago

Will there be a way to disable Change Account button if we already provide one?

ReDreamport commented 10 years ago

I think the account that user play the game with can differ from the one they use to pay. The xiaocong account is not only a Amazon account but also a Paypal account(for the money part). But if you do want to disable changing account, I could put an option in SDK.

thedmd commented 10 years ago

I will be helpfull since we already provide means to change account before every purchase. Changing it after invoking startMe() will break purchase system.

ReDreamport commented 10 years ago

Work done! If you pass a valid accessToken to SDK, we'll use it and prevent users from changing accounts.

thedmd commented 10 years ago

Thank you.

thedmd commented 10 years ago

Does passing accessToken from LoginActivity stop token renew code from working?

ReDreamport commented 10 years ago

We could refresh it. We'll cache the accessToken and the refreshToken.

thedmd commented 10 years ago

That would be nice since I have not means to do that.