Dreaded "Uh Oh. there was a problem" screen.

1,271 views
Skip to first unread message

mikeando

unread,
Dec 27, 2011, 7:47:56 PM12/27/11
to In-App Payments
So I'm still trying to integrate basic IAP into my application:

I get the UI up OK, initialize it with a JWT that it likes, login in a
fresh incognito window and with a newly created user.

But when I go to make the purchase I get the "Uh Oh. There was a
problem. We couldn't start your purchase because of a technical
issue." page.

If I look at the javascript log for the popup window then I see this:

ERROR: Failed to load resource: the server responded with a status of
500 (Internal Server Error) https://sandbox.google.com/checkout/inapp/purchase_options

And in the application window I see this:

ERROR: Unsafe JavaScript attempt to access frame with URL
https://localhost/google_iap/buy_page.html from frame with URL
https://sandbox.google.com/checkout/inapp/static/gwt/payments.html?viewportScreenCenterX=1076.5&viewportScreenCenterY=712.5#id=I1_1325032548328&parent=https%3A%2F%2Flocalhost&rpctoken=312713206&_methods=onPurchaseActionStatus%2CgetParameters%2CgetJwt%2C_ready%2C_close%2C_open%2C_resizeMe.
Domains, protocols and ports must match.

ERROR: Failed to load resource: the server responded with a status of
401 (Unauthorized) https://sandbox.google.com/checkout/inapp/purchase_options

I'm recording any accesses to my callback page and I see nothing
there, so I dont think it is that.

Is the sandbox misbehaving again? Or is it something else that I'm
doing?

Thanks,

Mike A.

mikeando

unread,
Dec 27, 2011, 8:08:07 PM12/27/11
to In-App Payments
Additional information - not sure if it will help, but in the
interests of completeness.

The call to https://sandbox.google.com/checkout/inapp/purchase_options
from the popup is returning a "500 Internal Server Error" status code.

The Request Payload for that request is:

[,"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIxNjg5MzcwNDMyNDc1MTcxNjUwMSIsImF1ZCI6Ikdvb2dsZSIsInR5cCI6Imdvb2dsZVwvcGF5bWVudHNcL2luYXBwXC9pdGVtXC92MSIsImV4cCI6MTMyNTAzNTIxMiwiaWF0IjoxMzI1MDMxNjEyLCJyZXF1ZXN0Ijp7Im5hbWUiOiJBIFdvb3psZSIsImRlc2NyaXB0aW9uIjoiQnV5IGEgY3V0ZSBsaXR0bGUgd29vemxlLiIsInByaWNlIjoiMTAuNSIsImN1cnJlbmN5Q29kZSI6IlVTRCIsInNlbGxlckRhdGEiOiJ7XCJwbGF5ZXJfaWRcIjpcIjI4NzMwNjk0MTM2NDAxODUxMDFcIixcImlrZXlcIjpcIndvb3psZVwifSJ9fQ.cKEtdLiruYoL3THI6Id9GoQL0YeGLEqUx3mlQcd03AE"]

Which looks like invalid JSON (As there is nothing before the first
",") but the string part is the JWT I'm using in the purchase.

The popup is then sending an exception message to the sandbox server:
It contains this (after URL decoding)

perm=91084A1BBF2CB3F6AF1E2968D089D637&module=com.google.checkout.inapp.client.gwt.init.init&msg={"classname":"Class
$S338", "message":"Unexpected response (500): ", "elements":
[{"declaringClass":"Unknown", "methodName":"Ew", "fileName":"0.js@16",
"lineNumber":428},{"declaringClass":"Unknown", "methodName":"Hw",
"fileName":"0.js@19", "lineNumber":322},{"declaringClass":"Unknown",
"methodName":"GD", "fileName":"0.js@19", "lineNumber":323},
{"declaringClass":"Unknown", "methodName":"fE",
"fileName":"0.js@14101", "lineNumber":1617},
{"declaringClass":"Unknown", "methodName":"jA", "fileName":"0.js@138",
"lineNumber":1308},{"declaringClass":"Unknown", "methodName":"POb",
"fileName":"0.js@7908", "lineNumber":1618},
{"declaringClass":"Unknown", "methodName":"<anonymous>",
"fileName":"0.js@65", "lineNumber":991}]}

Ed Chavez

unread,
Dec 28, 2011, 2:42:47 AM12/28/11
to in-app-...@googlegroups.com
Not a Googler so unsure if the sellerData you are passing is causing problems....

"sellerData":"{\"player_id\":\"2873069413640185101\",\"ikey\":\"woozle\"}"

see if changing it to a simple string "fixes"  it....(am also assuming everything else in your JWT is fine - e.g. exp, iat, and you are using sandbox id/secret for sandbox testing)..

Just tested sandbox and things are fine...

hth...

J

unread,
Dec 28, 2011, 8:28:54 AM12/28/11
to in-app-...@googlegroups.com
I'm having the exact same problem. At first I got as far as putting in the ficticious credit card details for my google id as per  http://code.google.com/apis/inapppayments/docs/testing.html but as soon as I clicked next I got this: "Uh oh. There was a problem." notice and since then it's been failing immediately (before I even seen the order page.

I can only assume its something on google's side.

J

unread,
Dec 28, 2011, 8:33:59 AM12/28/11
to in-app-...@googlegroups.com
Update:


I've just tested the google demo (you must be signed in with your seller account) and I get the same message. Definitely a google issue. You would think for a hefty 5% commission this system would be rather more robust.

J

Ed Chavez

unread,
Dec 29, 2011, 12:37:40 AM12/29/11
to in-app-...@googlegroups.com
You can't purchase from yourself.....you'll have to test with your implementation..I think that's what's going on. 

Yes, I did see the error when running from my sandbox page (the link you provided -> run demo). But if I test with my implementation, things are fine.
  • When testing with my implementation, I use a different sandbox account (email address) from the sandbox account associated with my implementation
  • Use different browsers if you are (already) logged into one of your sandbox accounts - not just a separate window, not just an incognito window (quirky - it may work though, but in the interest of saving time.....), use an entirely different browser - i.e. one Chrome, the other FF or IE or Safari.
  • I do go through some login issues when using Chromebook (incognito window) with errors like "too large" and other issues  - likely because of going against what I just mentioned about using a different browser...I have the time so I pushed onward but if you're debugging, it may drive you nuts (and I'm using a Chromebook right now - no other browser choice).
Maybe helpful - if you want to test an implementation...perhaps just to see if sandbox is down...feel free to use my test page:

J

unread,
Dec 29, 2011, 5:55:39 AM12/29/11
to in-app-...@googlegroups.com
Hi Ed,

I believe you. Your demo works perfectly. I've also tried the jwt within your site in my site and that also works, however the jwt I send through doesn't work.

This is an example of a jwt my app sends - closely based on the example:

eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJhdWQiOiAiR29vZ2xlIiwgImlzcyI6ICIxNzk5MzA2NTY4MDc1Njc5ODMxMyIsICJyZXF1ZXN0IjogeyJjdXJyZW5jeUNvZGUiOiAiVVNEIiwgInByaWNlIjogIjEwLjUwIiwgInNlbGxlckRhdGEiOiAidXNlcklEOjEyMjQyNDUsb2ZmZXJDT0RFOjMwOTg1NzY5ODcsYWZmaWxpYXRlOmFrc2RmYm92dTlqIiwgIm5hbWUiOiAiUGllY2Ugb2YgQ2FrZSIsICJkZXNjcmlwdGlvbiI6ICJWaXJ0dWFsIGNob2NvbGF0ZSBjYWtlIHRvIGZpbGwgeW91ciB2aXJ0dWFsIHR1bW15In0sICJleHAiOiAxMzI1MTU4NzAzLCAiaWF0IjogMTMyNTE1NTEwMywgInR5cCI6ICJnb29nbGUvcGF5bWVudHMvaW5hcHAvaXRlbS92MSJ9.w5-mg9tAFod1ozgPN4OODYHdYnBiYkV3JB4cAndrxsQ

and if I use the decoder at http://code.google.com/apis/inapppayments/docs/jwtdecoder.html it seems that everything pops out correctly. I'm using my apps seller id and secret (for sandbox) but something is going wrong to kick up the "there was a problem screen". If only there was some kind of debug report ...

I've also tried putting the fields in the same order as your example but no luck. The only difference between the example your app provides:

eyJhbGciOiJIUzI1NiIsImtpZCI6IjEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiIxMjE3ODk0NTA3MTU0MTc1MDY3MCIsImF1ZCI6Ikdvb2dsZSIsInR5cCI6Imdvb2dsZVwvcGF5bWVudHNcL2luYXBwXC9pdGVtXC92MSIsImlhdCI6MTMyNTE1NDQ1MywiZXhwIjoxMzI1MTU1MDUzLCJyZXF1ZXN0Ijp7ImN1cnJlbmN5Q29kZSI6IlVTRCIsInByaWNlIjoiNC45OSIsInNlbGxlckRhdGEiOiJzb21lIHNlbGxlciB1bmlxdWUgZGF0YSIsIm5hbWUiOiJTb21lIFdpZGdldCBBcHAiLCJkZXNjcmlwdGlvbiI6IkFTUC5ORVQgd2ViIHBhZ2VzIHJhem9yIHRlc3QifX0.UaZBgGMC3DrCYUkyA0PCXkx_Xly77cXyCVHl-oo5I3Y

are the specific details of the purchase, and a entry "kid":"1" in the header - but I can't see how these make a difference. 

pying

unread,
Dec 29, 2011, 2:16:01 PM12/29/11
to In-App Payments
Are you trying to purchase with the same login as your merchant
account?  Also you have a space in your jwt:
5ZXJ faW
On Dec 29, 2:55 am, J <1jason.whatf...@gmail.com> wrote:
> Hi Ed,
>
> I believe you. Your demo works perfectly. I've also tried the jwt within
> your site in my site and that also works, however the jwt I send through
> doesn't work.
>
> This is an example of a jwt my app sends - closely based on the example:
>
> eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJhdWQiOiAiR29vZ2xlIiwgImlzcyI6IC IxNzk5MzA2NTY4MDc1Njc5ODMxMyIsICJyZXF1ZXN0IjogeyJjdXJyZW5jeUNvZGUiOiAiVVNEI iwgInByaWNlIjogIjEwLjUwIiwgInNlbGxlckRhdGEiOiAidXNlcklEOjEyMjQyNDUsb2ZmZXJD T0RFOjMwOTg1NzY5ODcsYWZmaWxpYXRlOmFrc2RmYm92dTlqIiwgIm5hbWUiOiAiUGllY2Ugb2Y gQ2FrZSIsICJkZXNjcmlwdGlvbiI6ICJWaXJ0dWFsIGNob2NvbGF0ZSBjYWtlIHRvIGZpbGwgeW 91ciB2aXJ0dWFsIHR1bW15In0sICJleHAiOiAxMzI1MTU4NzAzLCAiaWF0IjogMTMyNTE1NTEwM ywgInR5cCI6ICJnb29nbGUvcGF5bWVudHMvaW5hcHAvaXRlbS92MSJ9.w5-mg9tAFod1ozgPN4O ODYHdYnBiYkV3JB4cAndrxsQ
>
> and if I use the decoder athttp://code.google.com/apis/inapppayments/docs/jwtdecoder.htmlit seems

J

unread,
Dec 29, 2011, 2:43:15 PM12/29/11
to in-app-...@googlegroups.com
Hi pying,

thank you for your reply.

I am using a different google account (newly created) in an all together different browser with all cookies cleared just prior to logging in to make the purchase.

I am using python and I've checked a few different jwt's that have been sent from my server to the client and no spaces are evident (using jwt_string.find(" "). I think it may have been an error in copying the string. I've attached a textfile with a sample jwt but in case your reluctant to open it I've also put it in a  jsFiddle (http://jsfiddle.net/YhDpQ/ ) and if all those fail here's another example:

eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJhdWQiOiAiR29vZ2xlIiwgImlzcyI6ICIxNzk5MzA2NTY4MDc1Njc5ODMxMyIsICJyZXF1ZXN0IjogeyJjdXJyZW5jeUNvZGUiOiAiVVNEIiwgInByaWNlIjogIjEwLjUwIiwgInNlbGxlckRhdGEiOiAidXNlcklEOjEyMjQyNDUsb2ZmZXJDT0RFOjMwOTg1NzY5ODcsYWZmaWxpYXRlOmFrc2RmYm92dTlqIiwgIm5hbWUiOiAiUGllY2Ugb2YgQ2FrZSIsICJkZXNjcmlwdGlvbiI6ICJWaXJ0dWFsIGNob2NvbGF0ZSBjYWtlIHRvIGZpbGwgeW91ciB2aXJ0dWFsIHR1bW15In0sICJleHAiOiAxMzI1MTkxMDU5LCAiaWF0IjogMTMyNTE4NzQ1OSwgInR5cCI6ICJnb29nbGUvcGF5bWVudHMvaW5hcHAvaXRlbS92MSJ9.JsFeszvw9_Q15OCZNZiRqWrUlMseQK0dg5pEaAL0rXg

If I put this directly into http://code.google.com/apis/inapppayments/docs/jwtdecoder.html I get:


{"alg":"HS256","typ":"JWT"}

{
 "aud":"Google",
 "iss":"17993065680756798313",
 "request":{"currencyCode":"USD",
 "price":"10.50",
 "sellerData":"userID:1224245, offerCODE:3098576987, affiliate:aksdfbovu9j",
 "name":"Piece of Cake",
 "description":"Virtual chocolate cake to fill your virtual tummy"
},
 "exp":1325191059,
 "iat":1325187459,
 "typ":"google/payments/inapp/item/v1"}

JsFeszvw9_Q15OCZNZiRqWrUlMseQK0dg5pEaAL0rXg


Any ideas?
untitled.txt

mikeando

unread,
Dec 29, 2011, 10:08:48 PM12/29/11
to In-App Payments
This is exactly the same for me now too.
Reordered fields of the JWT to match Eds.
Changed the content of the fields to matc Eds.
Checked the seller secret and seller identity used.

So the only differences between my JWT and Eds is:

* The order of the header fields:
* Mine is {"typ":"JWT","alg":"HS256"}
* Eds is {"alg":"HS256","kid":"1","typ":"JWT"}
* The seller id. (iss field).
* The iat and exp fields. Mine differ by 3600, rather than the 600 in
eds.
* The signature - which we'd expect to be different.

However the signature and header are getting created by the JWT php
package.

So I'm guessing its either a mismatch between the signature and the
iss field. or something to do with the kid field in the header.

Mike A.

mikeando

unread,
Dec 29, 2011, 11:01:40 PM12/29/11
to In-App Payments
Just a further note:

Changing the PHP JWT library so that the JWT header fields are in
the same order as Eds and contain the "kid" field doesn't solve
anything.

Mike A.

J

unread,
Dec 30, 2011, 4:47:17 AM12/30/11
to in-app-...@googlegroups.com
Hi Mike,

I'm glad it's not just me having this problem. Along with the checks I mentioned above, I also looked to see whether I was encrypting with the correct algorithm as per (http://code.google.com/apis/inapppayments/docs/jsreference.html#jwt) and when not specified the library auto-selects SHA-256 signatures, as required. You may wish to check the same thing with your php library, just so we can rule this out for the googlers who I hope will be along any minute to make all the problems go away.

I've attached the python jwt library I'm using, in case anyone is keen to have a look.

J
jwt.py

J

unread,
Dec 30, 2011, 9:14:50 AM12/30/11
to in-app-...@googlegroups.com
UPDATE:

I've also just tried with the jwt library at: http://code.google.com/p/iap-hello-world/source/browse/#git%2Fjwt just to make sure it wasn't a library related encoding issue. I get the same problem.

Ed Chavez

unread,
Dec 30, 2011, 9:24:21 AM12/30/11
to in-app-...@googlegroups.com
Just to circle back...
  • When are you seeing the error? When I said I could reproduce the error in my Google Sandbox (run demo) page, it was after I submitted a purchase. This means all the JWT stuff is "done" (or at least the jwt being discussed above - otherwise, if memory serves, you wouldn't even see the purchase pop up), 
        
  • If that's the case, then check your handler and see if you are handling the callback properly. 

Ed Chavez

unread,
Dec 30, 2011, 9:28:45 AM12/30/11
to in-app-...@googlegroups.com
Sorry, meant the "postback" (to your handler).....

J

unread,
Dec 30, 2011, 10:11:54 AM12/30/11
to in-app-...@googlegroups.com
Hi Ed,
 
This is what  I am doing. In a seperate browser (Firefox when I usually use chrome), cookies cleared with a new and unrelated-to-anything google account.
 
1) Click on the buy button
2) Purchase pop up displayed with product details (presumably from jwt) and if relevant a banner that says "Sign in with your Google account to complete your purchase."
3) Click start now
4) redirects me to login screen
5) Log in
6) [for new user] prompts me to add payment details
7) [for new user] I add the "fake" / "test" credit cards suggested in the getting started guide. I've used both AMEX and VISA for 2 different users.
8) Redirects me to the purchase pop-up, waits for a minute with the blue ajax spinner
9) Redirects me to the:
 

"Uh oh. There was a problem.

We couldn't start your purchase because of a technical issue."

I have no real reason to suspect jwt, or anything else really. I'm just trying to find the problem and that's where I started looking. Unfortuantely there's no stack trace or debug report for this so it's not clear what else I can do to get this working.
 
J

mikeando

unread,
Jan 3, 2012, 2:48:25 AM1/3/12
to In-App Payments
Again this is the same for me:The error is occurring _before_ I'd
expect any calls to my postback handler. (Which I'm not seeing any
calls to at the moment either).
To be more explicit  * Clear my cache * Load the web page. (Your
example with my JWT in it) * I click the link to purchase the object.
- popup opens. * Click the login button. * Popup temporarily flashes
to "review your purchase" then automatically goes to   "Uh Oh. There
was a problem".
Mike A.

pying

unread,
Jan 3, 2012, 10:17:52 AM1/3/12
to In-App Payments
Do you have the URL of a page that where we can test your
implementation?

J

unread,
Jan 8, 2012, 12:02:19 PM1/8/12
to in-app-...@googlegroups.com
Hi there,

This problem is still persisting and I've tried it with two different sandbox accounts and freshly created google accounts.

I've put together a very simple implementation here: http://test-psi-alpha.appspot.com/

I can post the code that drives this in the backend if required.

J

Avanish

unread,
Jan 8, 2012, 8:21:10 PM1/8/12
to In-App Payments
Hi J

In the "In-App Payments settings" try your implementation first by
having nothing (blank) set in the "Postback URL:" field .

After that if you did have something set in the filed, you will need
to see your server access log to check if there is a POST from Google
server. If you did not see anything than it may be the postback url is
not valid. Currently i have found it does not like parametric url, it
works fine with clean url.
The post from the Google server needs to be properly decoded and
compared with your secret key. You will need to respond with the
response.orderId field value of the JSON string.


Avanish

mikeando

unread,
Jan 8, 2012, 8:40:12 PM1/8/12
to In-App Payments
Hi Avanish,

What is the expected behaviour if there is nothing set in the postback
URL?

Mike A.

On Jan 9, 11:21 am, Avanish <avanish.bhar...@gmail.com> wrote:
> Hi J
>
> In the "In-App Payments settings" try your implementation first by
> having nothing (blank) set in the "Postback URL:" field .

-- snip --

Avanish

unread,
Jan 8, 2012, 10:25:36 PM1/8/12
to In-App Payments
Hi Mike

You should come to the 'Thank you for your purchase' screen. Go back
to your sandbox Merchant Center and check the Order tab.

If you do have some url set in the field, check your server log for
POST from Google. If its posting you will have to answer back with a
simple html with orderId in the body.

Avanish

J

unread,
Jan 9, 2012, 4:07:58 AM1/9/12
to in-app-...@googlegroups.com
Hi Avanish,

I do and did indeed have nothing in the postback url (it was blank) and as you see it still isn't working.

As for the postback url is it possible (when the blank status starts working) to have a localhost url (for local development)?

J

Avanish

unread,
Jan 9, 2012, 5:23:03 AM1/9/12
to In-App Payments
Hi J

I tried your link and It feels like the jwt string has expired time.

I recommend you go back to the first steps and debug your code.

1. If you want to see something working and to get some confidence
have a look at the demo

https://sandbox.google.com/checkout/customer/gadget/inapp/demo.html?hl=en_US

Try just copying the JWT string and paste it in your code and run it
quickly before the exp. Know that the value for iat and exp. The exp
must not expire otherwise you will get issues.

2. Generate the JWT string on the server side with just variable iat
and exp value and see if all is going well.

something like ( i am using object pascal so change to your taste)
iat := IntToStr ( floor(Now.getTime/1000));
exp := IntToStr (( floor(Now.getTime/1000)) + 3600);

If all this is working fine then you can tackle the postback url step.
You can not use local host. Try dumping the post in a database and
have a special debug page htm to read the text from there

You can do something like this in your server side code


If StringsEqual(Request.UrlPageName,'GoogleFeedBack') Then //the
url you feed into the settings field
Begin
S := Request.getAsText;

P := Pos ( '=', S ); //delete the jwt= before
parsing as JSON object
Delete ( S, 1, P );
PayLoad := DecodeJWT ( S ); // see the decode function
in one of the libs

id := ExtractJWT( PayLoad ); //apply your JSON parser
with the STRING/ ours returns the order id

InsertGoogleAckToken (id ); //insert the order id in
database to check against the client side or whatever you want
//write the response with id in the body
WriteLnString('<html><head>' );
WriteLnString('</head>' );
WriteLnString('<body>' );
WriteLnString( id );
WriteLnString('</body></html>');
End Else

Inherited Execute; // else process the pages normally


See how you go..

Cheers,
Avanish

mikeando

unread,
Jan 9, 2012, 7:12:40 AM1/9/12
to In-App Payments
Hi Avanish,

I've tried with an empty callback now.
It is still failing in the same way.

This is not due to an expired JWT, That gives a different error
message.
Its also not due to an bad JSON or signature in the JWT, as these both
also give different
messages.

It seems to me that the key part of this issue is that the JSON passed
from the UI to the google servers is not valid json.

In particular the call to "https://sandbox.google.com/checkout/inapp/
purchase_options" is returning with a 500 (internal server error) and
the request body is

[,"eyJhbGciOiJI....S89jQtV0VM"]

where the second argument is the JWT for the purchase, but the first
argument is missing (And thus the json is invalid).

An error report is then sent back to google through the
https://sandbox.google.com/checkout/inapp/exception URL, its content
is:

module: com.google.checkout.inapp.client.gwt.init.init
msg: {"classname":"Class$S383", "message":"Unexpected response
(500): ", "elements":[{"declaringClass":"Unknown",
"methodName":"anonymous", "fileName":"null", "lineNumber":-1}]}

I've tried to work out what's going on in the javascript, but the
compiled javascript is kinda cryptic.

Mike A.

mikeando

unread,
Jan 9, 2012, 8:10:24 AM1/9/12
to In-App Payments
I've created a minimal PHP example that causes the problem for me:

You can find the code here: https://gist.github.com/397a0fc8ea7f361e0da4
All you should need is the JWT.php library and replace with your
seller ID and seller secret.

I don't have a version on a public server that uses my seller secret,
but it
certainly gives me the internal server error when I run it locally.

Mike A.


On Jan 9, 10:12 pm, mikeando <drmikea...@gmail.com> wrote:
> Hi Avanish,
>
> I've tried with an empty callback now.
> It is still failing in the same way.
>
> This is not due to an expired JWT, That gives a different error
> message.
> Its also not due to an bad JSON or signature in the JWT, as these both
> also give different
> messages.
>
> It seems to me that the key part of this issue is that the JSON passed
> from the UI to the google servers is not valid json.
>
> In particular the call to "https://sandbox.google.com/checkout/inapp/
> purchase_options" is returning with a 500 (internal server error) and
> the request body is
>
> [,"eyJhbGciOiJI....S89jQtV0VM"]
>
> where the second argument is the JWT for the purchase, but the first
> argument is missing (And thus the json is invalid).
>
> An error report is then sent back to google through thehttps://sandbox.google.com/checkout/inapp/exceptionURL, its content

Avanish

unread,
Jan 9, 2012, 9:21:38 AM1/9/12
to In-App Payments
Hi Mike,

I do not see those error message. I just ran my implementation in
firefox and saw the https://sandbox.google.com/checkout/inapp/purchase_options
401 unauthorized
but it lets me complete the flow.

Just a thought and to double check the initial JSON and encryption.

Can you Base64urlDecode the header and payload and see if JSON string
is same as the one you passed.

I hope it helps.

Avanish




On Jan 9, 11:12 pm, mikeando <drmikea...@gmail.com> wrote:
> Hi Avanish,
>
> I've tried with an empty callback now.
> It is still failing in the same way.
>
> This is not due to an expired JWT, That gives a different error
> message.
> Its also not due to an bad JSON or signature in the JWT, as these both
> also give different
> messages.
>
> It seems to me that the key part of this issue is that the JSON passed
> from the UI to the google servers is not valid json.
>
> In particular the call to "https://sandbox.google.com/checkout/inapp/
> purchase_options" is returning with a 500 (internal server error) and
> the request body is
>
> [,"eyJhbGciOiJI....S89jQtV0VM"]
>
> where the second argument is the JWT for the purchase, but the first
> argument is missing (And thus the json is invalid).
>
> An error report is then sent back to google through thehttps://sandbox.google.com/checkout/inapp/exceptionURL, its content

Avanish

unread,
Jan 9, 2012, 5:24:20 PM1/9/12
to In-App Payments
Hi Mike,

I believe currently the in-app gui does not like multiple items in the
request ( as array of JSON string). I tried to add multiple items and
make the request and array of items. It fails.

The php has array and it may be the culprit. Can you try and remove
the Array in the payload request part of the json paylod and try it. I
do not use php so can you see that the output of the JSON string does
not have [ ] array markers

Avanish

mikeando

unread,
Jan 9, 2012, 9:13:59 PM1/9/12
to In-App Payments
Hi Avanish,

`array` is used for creating PHP dictionaries as well as typical
arrays.
I've changed the source of the code above to print out the json for
the JWT
head and body of the request, and they do not contain any json arrays,
only json objects.

The only difference between my input and the output json is that the
"typ" key is set to

"typ":"google\/payments\/inapp\/item\/v1"

which is valid json. (Escaping of the "/" character is optional in
json).

Mike A.

mikeando

unread,
Jan 9, 2012, 9:22:42 PM1/9/12
to In-App Payments
Hi Avanish,

I don't get a 401 error on purchase_options, I get a 500 (internal
server error).
And I definitely can't complete the flow.

I've checked the JSON, and the signature .. it all _seems_ fine.

As I said, I'm sure this 500 error is the key to the whole puzzle.
I don't know why I'm getting it and other people are not. The error
doesn't come with any useful diagnostics - at least
nothing that is useful to a developer.


Maybe its something related to the setup in my account?

Mike A.


On Jan 10, 12:21 am, Avanish <avanish.bhar...@gmail.com> wrote:
> Hi Mike,
>
> I do not see those error message. I just ran my implementation in
> firefox and saw thehttps://sandbox.google.com/checkout/inapp/purchase_options

Avanish

unread,
Jan 9, 2012, 9:33:38 PM1/9/12
to In-App Payments
Hi Mike

When you Base64urlDecode the header, you should get back the exact
string you passed including the /

so if i decode i get.
{"iss":"etc..","aud":"Google","typ":"google/payments/inapp/item/
v1",etc...

I am not using php so try it and see what is the php urlsafeB64Decode
is doing.

Here is my functions for decoding, check to see what you have
equivalent in your language library

{...............................................................................}
Function Base64urlEncoding ( Const Value: String ) : String;
Var
S : String;
Begin
S := EncodeBase64 ( Value );
S := replaceString ( S,'+','-' );
S := replaceString ( S,'/','_' );
Result := replaceString ( S, '=', '' );
End;
{...............................................................................}

Function Base64urlDecoding ( Const Value : String ) : String;
Var
S : String;
Begin
S := DecodeBase64 ( Value );
S := replaceString ( S,'-','+' );
S := replaceString ( S,'_','/' );
Result := S;
End;
{...............................................................................}

{...............................................................................}
Function DecodeJWT( EncodedJWT : String ) : String;
Var
JWTHeader, PayLoad, Signature : String;
SignedSignature : String;
S : String;
Begin
Result := '';

JWTHeader := Base64urlDecoding
( parseCh( EncodedJWT,'.'));
PayLoad := Base64urlDecoding
( parseCh( EncodedJWT,'.'));

Signature := EncodedJWT;

S := Base64urlEncoding ( JWTHeader ) + '.' +
Base64urlEncoding( PayLoad );
SignedSignature := Base64urlEncoding ( DCPHMAC_SHA256 ( S,
cJWTSecret ));

If SignedSignature = Signature Then
Result := PayLoad;
End;
{...............................................................................}

mikeando

unread,
Jan 9, 2012, 10:29:40 PM1/9/12
to In-App Payments
Hi Avanish

After having a deeper look, the base64 encoding/decoding seems fine.

My requests typ value is getting serialised to json as
"google\/payments\/inapp\/item\/"
. So the result coming out of the base64 encoding is identical to that
coming in.

And after json decoding the objects are identical too.

Mike A.

Ed Chavez

unread,
Jan 9, 2012, 10:43:56 PM1/9/12
to in-app-...@googlegroups.com
Mike,

Unsure if this is helpful...just trying to give you more info...



[,"eyJhbGciOiJI....S89jQtV0VM"] 

where the second argument is the JWT for the purchase, but the first 
argument is missing (And thus the json is invalid). 

I don't think this is the issue...inspecting the request in my implementation is the same:

[,"eyJhbGciOiJIUz....

I've also tried your headers and payload (of course using my own sandbox id/secret and generating my own iat and exp) and its fine - I thought it was the space or the escaping (as Avanish pointed out), but they don't seem to be the issue (re: I used them verbatim to generate my jwt).

The "401" is "normal" as well - it occurs when the user hasn't logged into Google Account....

The error for bad signature is also explicit - it says something to that effect (I tested it, and in the "uh oh" page, it will say something that points to a bad signature)....and its immediate.

If your exp is "bad" it will mention it in the error (purchase timed out).

When I test your link (appspot), I do get the error after I login to my sandbox account - the initial popup is fine - which (at least to me) means your JWT is fine - (so if you see the 500 immediately, it likely means you are still logged into some Google Account - as above, if you're not, you should see the 401 and login screen).

I've tried mixing sandbox/production, using a dummy ID, to generate an error, and they all do immediately (no pop up - in other words, if any of these are issues, it won't even get you to the "login" stage)....

You can't use "localhost" for postback url - that would be invalid (in the context of Google, that would be "their" box). I have never tried this, and while it doesn't sound like the culprit, at this point it wouldn't hurt to use a valid postback url.....

mikeando

unread,
Jan 9, 2012, 11:24:02 PM1/9/12
to In-App Payments
Thanks Ed,

Its good to know that its not the format of the request that is
broken. Rules out one more thing on my side.

The 500 I get from the server is after logging in a test user through
the UI in a separate browser after clearing that browsers history,
cookies etc.

Your experience with errors also matches mine. Most of the "bad"
things you can do the JWT report errors early on in the process,
(and with a diagnostic message) which is not what is happening
with this error.

I've not been using local host for a callback URL. (that was a
question from J), I was originally testing using a ssh tunnel to my
local box, so that the URL looked like this
http://myserver.com:18000/callback
Which was then getting forwarded to my box. (I've used similar
setups for testing facebook apps previously). However on the
suggestion of Avanish I've removed the callback URL altogether
... with the same problem persisting.

It seems like I've covered all the sane bases ... I'm going to guess
that its something odd between the user account I'm using and the
sandbox. I'm going to try creating a completely new developer
account and see if using its settings will work.

It'd be nice if someone could try running my PHP example
( https://gist.github.com/397a0fc8ea7f361e0da4 ) somewhere with their
user info, just to be 100% sure its not something in my code.

Mike A.

Avanish

unread,
Feb 2, 2012, 4:36:38 AM2/2/12
to In-App Payments
Hi Mike,

I've created a gadget that may help users in the community. You can
test it with your sandbox credentials only.

http://inappstore.analyticsworkspace.com/

Let me know if you encounter any issues.

Avanish
> (https://gist.github.com/397a0fc8ea7f361e0da4 ) somewhere with their

ESGames

unread,
Feb 13, 2012, 12:29:15 PM2/13/12
to in-app-...@googlegroups.com
Hi guys,

Was this ever resolved? I'm currently experiencing the exact same issue.

- I'm testing on a different account in a different browser
- The login screen appears and I also see my item info correctly, so my JWT seems valid
- After logging in (I've already associated a test credit card) I get the 'Uh oh' screen

mikeando

unread,
Feb 14, 2012, 4:10:00 AM2/14/12
to In-App Payments
I was never able to resolve it,
So instead of testing using the sandbox, I'm testing using a
production server and items with small $ values.
The user I'm testing with was also set up by a coleague of mine, using
US settings.

So far this seems to be working OK.

Haven't tried the callbacks yet, but with no callback set I get
confirmation of purchase,
which is much further than I was getting with the sandbox user.

Hope this helps,

Mike A.

Daniel Florey

unread,
Feb 14, 2012, 4:18:13 AM2/14/12
to in-app-...@googlegroups.com
Yes, we also dropped the sandbox quickly and testing in production turned out to work painless.
Reply all
Reply to author
Forward
0 new messages