rsolomakhin / rsolomakhin.github.io

https://rsolomakhin.github.io/
Apache License 2.0
30 stars 45 forks source link

Incorrect Android/PaymentRequest Info #28

Open cyberphone opened 5 years ago

cyberphone commented 5 years ago

I'm trying to follow the guidelines in: https://developers.google.com/web/fundamentals/payments/payment-apps-developer-guide/android-payment-apps Although I have got it to work I find it confusing. The lack of a single custom Android app is also making things unnecessary difficult.

The reference to https://w3c.github.io/payment-method-manifest makes no sense since it appears to cover another kind of manifest than needed by Android native apps. fingerprints is not specified in this document.

It is not entirely obvious how you can develop code without having a public server holding the payment manifest. I solved this by creating a CA certifying IP addresses and adding the root to emulators and devices. Payment method: https://192.168.1.79:8442/w3cpay/method

I don't understand the rationale for the HTTP HEAD and Link solution. If you are able supporting a custom HEAD on a server, why couldn't the manifest be at the same URL? If there is no Link, Chrome might as well perform GET on the same URL.

BTW, I couldn't get manifest caching to work in a reasonable manner. Since you get serious problems if this scheme isn't working, I think a better description would be appropriate. Currently I run without caching.

There are strange things in the code samples as well:

Parcelable[] certificateChain;
Bundle certficate = new Bundle();
certificate.putByteArray("certificate", certificateByteArray[i]);
certificateChain[i] = certificate;
extras.putParcelableArray("certificateChain", certificateChain);

The i is what?

cyberphone commented 5 years ago

That you can combine manifest files is also not entirely obvious:

{
  "default_applications": ["https://bobpay.com/manifest.json"],
  "related_applications": [{
    "platform": "play",
    "id": "com.bobpay.pay",
    "min_version": "1",
    "fingerprints": [{
      "type": "sha256_cert",
      "value": "85:0B:99:03:54:CE:71:6E:18:7C:43:1F:7F:C1:F1:5E:9B:81:84:1D:36:CE:F3:
F6:E2:97:15:70:79:7F:B0:F7"
     }]
  }],
  "supported_origins": "*"
}
rsolomakhin commented 5 years ago

I'm trying to follow the guidelines in: https://developers.google.com/web/fundamentals/payments/payment-apps-developer-guide/android-payment-apps Although I have got it to work I find it confusing.

Sorry about that, Anders! I will try to make it more clear.

The lack of a single custom Android app is also making things unnecessary difficult.

Good point! I should've linked to the following examples:

  1. https://bobpay.xyz/ has link to a sample app:
    1. APK
    2. Source
  2. Google Pay (Tez) is also using this API.

The reference to https://w3c.github.io/payment-method-manifest makes no sense since it appears to cover another kind of manifest than needed by Android native apps.

Could you tell me more about the confusion around payment method manifest? I will try to clarify.

fingerprints is not specified in this document.

fingerprints is specified in https://w3c.github.io/manifest/#fingerprints-member.

It is not entirely obvious how you can develop code without having a public server holding the payment manifest. I solved this by creating a CA certifying IP addresses and adding the root to emulators and devices. Payment method: https://192.168.1.79:8442/w3cpay/method

We've heard this feedback from other web developers as well, so Web Payment APIs in Chrome 76 now respect the command line flags --ignore-certificate-errors for self-signed certs and --unsafely-treat-insecure-origin-as-secure=http://some-test-server for non-HTTPS development.

This wiki describes how to pass command line flags to Chrome on Android:

I don't understand the rationale for the HTTP HEAD and Link solution.

The original rationale was to use payment methods that are easy to remember, such as google.com/pay or android.com/pay. In fact, Chrome has shipped with support for android.com/pay even before the whole idea of manifests was introduced into Web Payment APIs. However, such URLs usually contain marketing material and developer documentation. So once we needed to map android.com/pay and google.com/pay from URL to a JSON file, we could neither change the identifier URL (because of existing integrations) nor change the content of these URLs (because of existing links). So the Link solution was used. I hope it's not too much hustle...

If you are able supporting a custom HEAD on a server, why couldn't the manifest be at the same URL? If there is no Link, Chrome might as well perform GET on the same URL.

That's a great idea! I actually have not considered it before. Let's add it to the payment method manifest spec: https://github.com/w3c/payment-method-manifest/issues/10#issuecomment-519905351

BTW, I couldn't get manifest caching to work in a reasonable manner. Since you get serious problems if this scheme isn't working, I think a better description would be appropriate. Currently I run without caching.

Oh yeah, the caching is a mess at this time. We need to figure out how to rebuild that whole component using some standard, like HTTP Caching. Currently we cache the manifests for 90 days and refresh them on every PaymentRequest call. It's not ideal, because web developers might change their manifests frequently when first building the API, but this caching scheme makes retrieval of the latest manifest files cumbersome. I recommend that, if you want your PaymentRequest object to be using the latest manifests, the code should first create a dummy PaymentRequest object that will cause the cache refresh, then create a second real PaymentRequest object that will be using the latest manifest files.

There are strange things in the code samples as well:

Parcelable[] certificateChain;
Bundle certficate = new Bundle();
certificate.putByteArray("certificate", certificateByteArray[i]);
certificateChain[i] = certificate;
extras.putParcelableArray("certificateChain", certificateChain);

The i is what?

The i is the index into the array of certificates. This code in particular is for browsers that implement this API. Here's how it's implemented in Chrome: Link.


Thank you for trying the API! Would you be interested in sharing your experience at the W3C TPAC this September?

cyberphone commented 5 years ago

Thanx Rouslan, This was exactly what I was looking for!!! It couldn't be better.

In case you have time to update the document it might be useful putting browser implementation details in a separate document and only keep links to that in the "users guide". Or maybe linking in the other direction would be even more logical?


I would love to go to TPAC but 1) I have no funding 2) I just started with PaymentRequest for Android so my experiences are somewhat limited 3) I'm not a W3C member.

I'm currently trying to get this through the IETF ISE process: https://tools.ietf.org/html/draft-rundgren-json-canonicalization-scheme-06 so that signed JSON data in for example PaymentRequest still can be featured as JSON rather than Base64Url: https://mobilepki.org/jws-jcs/validate