Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How do developers test in-app payments?

28 views
Skip to first unread message

Kumar McMillan

unread,
Jan 23, 2013, 3:40:45 PM1/23/13
to dev-w...@lists.mozilla.org, Raymond Forbes, David Bialer
Hi all.
We're rapidly approaching the day when third party app developers can begin testing web payments using navigator.mozPay() [1] against Mozilla's Web Payment Provider [2]. I'd like to get some feedback on ideas for how developers can *test* their use of the API.

[1] https://wiki.mozilla.org/WebAPI/WebPayment
[2] https://wiki.mozilla.org/WebAPI/WebPaymentProvider

Some info on those wiki pages is outdated already (fixes are coming). Here is a summary of how developers will set up payments:

The developer...
- submits app to Firefox Marketplace
- activates in-app payments
- enters bank details to receive money
- clicks a button to generate a secret key
- hosts an app on a server
- writes server code to sign JWTs (JSON Web Tokens) with the secret key
- hosts two URLs, a postback and a chargeback
- creates purchase button in app that calls nav.mozPay([signedJWT])

How does a developer test this? She will want to know:

1. Did I sign my JWT correctly, is the format OK, etc?
2. Are my postbacks and chargebacks hooked up correctly to my client code?

The second question is the most important because this is how the app developer protects against malicious attackers stealing digital goods. The postback needs to reconcile the product and probably also the user identity which would all be managed internally by the app.

Here is an example of constructing and signing a JWT request:

token = jwt.encode({
"iss" : appIdFromMarketplace,
"aud" : "marketplace.firefox.com",
"typ" : "mozilla/payments/v1/pay",
"exp" : 1337357297,
"iat" : 1337360897,
"request" : {
"name" : "Unlock Level 10",
"description" : "The most exciting level in the game! Dungeons! Fire!",
"id": "unique-id-for-product",
"pricePoint": 1, // This might convert to USD 0.99, EUR 0.89, BRL 1.20
"productData" : "my_product_id=1234&my_user_id=345",
"postbackURL" : "http://castlgame.com/payments/postback",
"chargebackURL" : "http://castlegame.com/payments/chargeback"
}
}, secretKeyFromMarketplace)

The app fetches this JWT from the server and runs this JS code on the client when the user clicks buy:

var request = navigator.mozPay([signedJWT]);
request.onsuccess = function() {
// Poll the server, waiting for a successful postback...
};
request.onerror = function() {
console.log('Payment failed:', this.error.name);
// more DOMRequest checking...
};

Note that these success/error handlers on the client are not as useful as the server side postback/chargeback handlers. The former is more for UI errors like the user clicking the Cancel button. In order to fulfill payment, the developer must use a postback handler so she can verify the JWT signature.


TEST PROPOSAL

The developer could test successful payments by amending a JWT like this:

{
...
"request" : {
"name" : "Unlock Level 10",
...
"simulate": {
"result": "postback"
},
}
}

That is, add a simulate option to the request that describes what to simulate. The above code would run against the same production server configured in shipping devices (and Firefox OS Simulator). When the server sees the simulate option it would never process any payment, it would simply say "Click this button to continue the simulation". In this case, that button would do a real postback to the app developer's server as if a real payment went through successfully. The developer could then test their product delivery mechanism without sending a real payment through. Since postbacks receive a copy of the original JWT then the dev could detect if it were a test via the simulate option.

To simulate an error, the option would be:

{
"request" : {
...
"simulate": {
"result": "chargeback",
"reason": "Insufficient funds"
},
}
}

Chargeback reasons aren't very well defined yet but this object model would allow us to add properties as needed in the future.

What are your thoughts on this? Either from the developer perspective, the server perspective, security-wise, etc. Would there be an easier or alternate way for developers to test payments?

One optimization is that we can require developers to generate a special secret key just for testing purposes. Thus the developer would not have to store a production key on their development/test server. The test key would only allow the simulate option and could never be used to process real payments.


thanks, Kumar

Andy McKay

unread,
Jan 23, 2013, 7:54:12 PM1/23/13
to Kumar McMillan, dev-w...@lists.mozilla.org, Raymond Forbes, David Bialer

On 2013-01-23, at 12:40 PM, Kumar McMillan <kmcm...@mozilla.com> wrote:

> Hi all.
> We're rapidly approaching the day when third party app developers can begin testing web payments using navigator.mozPay() [1] against Mozilla's Web Payment Provider [2]. I'd like to get some feedback on ideas for how developers can *test* their use of the API.
>
> [1] https://wiki.mozilla.org/WebAPI/WebPayment
> [2] https://wiki.mozilla.org/WebAPI/WebPaymentProvider

We've got to make a plan to reenable and get started on the MDN docs too.

> Some info on those wiki pages is outdated already (fixes are coming). Here is a summary of how developers will set up payments:
>
> The developer...
> - submits app to Firefox Marketplace
> - activates in-app payments
> - enters bank details to receive money

If its a paid app, they can stop here and we move on to receipt checking. Simpler for them at least.

> - clicks a button to generate a secret key
> - hosts an app on a server
> - writes server code to sign JWTs (JSON Web Tokens) with the secret key
> - hosts two URLs, a postback and a chargeback
> - creates purchase button in app that calls nav.mozPay([signedJWT])

> Note that these success/error handlers on the client are not as useful as the server side postback/chargeback handlers. The former is more for UI errors like the user clicking the Cancel button. In order to fulfill payment, the developer must use a postback handler so she can verify the JWT signature.

We should be write a simple example server that does copes with postback/chargeback handlers.

> TEST PROPOSAL
>
> The developer could test successful payments by amending a JWT like this:
>
> {
> ...
> "request" : {
> "name" : "Unlock Level 10",
> ...
> "simulate": {
> "result": "postback"
> },
> }
> }

This seems fine to me. The post back and chargebacks would come through on the developers end with that JWT in, so they'd know it was a simulated request and can ignore it. It's a bit of a pain on the server as we'll have a special code path that involves not calling Bango and faking some things out.

David Bialer

unread,
Jan 23, 2013, 8:01:42 PM1/23/13
to Kumar McMillan, dev-w...@lists.mozilla.org, Raymond Forbes


>
> That is, add a simulate option to the request that describes what to
> simulate. The above code would run against the same production
> server configured in shipping devices (and Firefox OS Simulator).
> When the server sees the simulate option it would never process any
> payment, it would simply say "Click this button to continue the
> simulation". In this case, that button would do a real postback to
> the app developer's server as if a real payment went through
> successfully. The developer could then test their product delivery
> mechanism without sending a real payment through. Since postbacks
> receive a copy of the original JWT then the dev could detect if it
> were a test via the simulate option.
>
Perhaps this should have a button for each success and error condition as well as a chargeback button.
Buttons:
* Simulate Success
* Simulate Fail (App Unavailable)
* Simulate Fail (Purchase cancelled)
* ...
* Simulate Chargeback

Kumar McMillan

unread,
Jan 23, 2013, 8:04:35 PM1/23/13
to Andy McKay, dev-w...@lists.mozilla.org, Raymond Forbes, David Bialer

On Jan 23, 2013, at 6:54 PM, Andy McKay <amc...@mozilla.com> wrote:

>
> On 2013-01-23, at 12:40 PM, Kumar McMillan <kmcm...@mozilla.com> wrote:
>
>> Hi all.
>> We're rapidly approaching the day when third party app developers can begin testing web payments using navigator.mozPay() [1] against Mozilla's Web Payment Provider [2]. I'd like to get some feedback on ideas for how developers can *test* their use of the API.
>>
>> [1] https://wiki.mozilla.org/WebAPI/WebPayment
>> [2] https://wiki.mozilla.org/WebAPI/WebPaymentProvider
>
> We've got to make a plan to reenable and get started on the MDN docs too.

Yep. We have been iterating on the API a lot but the dust is beginning to settle. We are tracking docs in https://bugzilla.mozilla.org/show_bug.cgi?id=776678

>>
>> Note that these success/error handlers on the client are not as useful as the server side postback/chargeback handlers. The former is more for UI errors like the user clicking the Cancel button. In order to fulfill payment, the developer must use a postback handler so she can verify the JWT signature.
>
> We should be write a simple example server that does copes with postback/chargeback handlers.

Agreed. We could also provide server libs to offer drop-in solutions. This was my idea behind http://moz_inapp_pay.readthedocs.org/en/latest/


-Kumar

Kumar McMillan

unread,
Jan 24, 2013, 3:27:09 PM1/24/13
to David Bialer, dev-w...@lists.mozilla.org, Raymond Forbes

On Jan 23, 2013, at 7:01 PM, David Bialer <dbi...@mozilla.com> wrote:
>>
>> successfully. The developer could then test their product delivery
>> mechanism without sending a real payment through. Since postbacks
>> receive a copy of the original JWT then the dev could detect if it
>> were a test via the simulate option.
>>
> Perhaps this should have a button for each success and error condition as well as a chargeback button.
> Buttons:
> * Simulate Success
> * Simulate Fail (App Unavailable)
> * Simulate Fail (Purchase cancelled)
> * ...
> * Simulate Chargeback

This is an interesting idea and could be added as an enhancement. My hesitation with it is that this functionality would need to be implemented in the mobile UI of the payment window. If instead we implement it in the JWT format of the payment request then it's baked into the API rather than baked into the server side implementation. Baking it into the JWT format makes 3rd party Web Payment Provider implementations more straight forward.

_

All the feedback on the thread (and on IRC) has been positive so I think we can move forward on implementing this. Thanks for the feedback. Naturally, we may discover issues with it as developers start using it.

This feature will be tracked here: https://bugzilla.mozilla.org/show_bug.cgi?id=834410

-Kumar

Kumar McMillan

unread,
Jan 24, 2013, 6:28:15 PM1/24/13
to David Bialer, dev-w...@lists.mozilla.org, Raymond Forbes

On Jan 24, 2013, at 2:27 PM, Kumar McMillan <kmcm...@mozilla.com> wrote:
>
> All the feedback on the thread (and on IRC) has been positive so I think we can move forward on implementing this. Thanks for the feedback. Naturally, we may discover issues with it as developers start using it.
>
> This feature will be tracked here: https://bugzilla.mozilla.org/show_bug.cgi?id=834410

Ian and I were chatting about this and we came up with a good optimization. In the current proposal, a developer has to do two things before she can even begin to simulate in-app payments:

- Submit an app and fill in all publishing details
- Enter in all bank account details (that's a long form!)

I filed this bug to optimize the process: https://bugzilla.mozilla.org/show_bug.cgi?id=834486

This would let the developer log into the Marketplace devhub and generate a generic test key to simulate payments with. This key wouldn't be tied to a real app and could never be used for real payments, only simulations. Once the app is working, the dev would need to go through the full submission and payment setup to get a production key for real in-app payments.

-Kumar

Kumar McMillan

unread,
Jan 24, 2013, 7:16:56 PM1/24/13
to Lisa Brewster, dev-w...@lists.mozilla.org, Raymond Forbes, David Bialer

On Jan 24, 2013, at 6:02 PM, Lisa Brewster <lbre...@mozilla.com> wrote:

> On 1/24/13 3:28 PM, "Kumar McMillan" <kmcm...@mozilla.com> wrote:
>
>> Ian and I were chatting about this and we came up with a good
>> optimization. In the current proposal, a developer has to do two things
>> before she can even begin to simulate in-app payments:
>>
>> - Submit an app and fill in all publishing details
>> - Enter in all bank account details (that's a long form!)
>
> Does the developer actually need to submit the app, or just start a
> submission and fill out all the details? Plz2not junk up my queue, kthx.
> =]

Hehe. I think this optimization would prevent a dev from submitting an app prematurely: https://bugzilla.mozilla.org/show_bug.cgi?id=834486

However, in the event where the developer submits an app and sets up bank details I don't think it will go into the review queue until they mark it as such. Hmm. We should verify that. The checkbox for "publish immediately" might put it in your queue.

-Kumar
0 new messages