WebAPI/WebPayment: Difference between revisions

no edit summary
No edit summary
Line 4: Line 4:


== Status ==
== Status ==
See {{bug|767818}} for the 'navigator.pay' implementation.
See {{bug|767818}} for the 'navigator.mozPay' implementation.


Currently only implemented for B2G.
Currently only implemented for B2G.
Line 22: Line 22:
= WebPayments Architecture (DRAFT) =
= WebPayments Architecture (DRAFT) =
== Introduction ==
== Introduction ==
The goal of this Web Payments architecture is to allow Open Web Apps to initiate a payment (or a refund) from the user for a virtual good via the <code>navigator.pay</code> function.
The goal of this Web Payments architecture is to allow Open Web Apps to initiate a payment (or a refund) from the user for a virtual good via the <code>navigator.mozPay</code> function.


An OWA should be able to access the in-app web payments services using an API (<code>navigator.pay</code>) exposed by the User Agent on the device (for the B2G use case). The UA must use an asynchronous message loop to convey billing requests and responses between the application and the Payment Processor (or Provider). In practice, the applications should never directly communicate with the Payment Processors's servers. Instead, the application should send billing requests to the UA via 'navigator.pay()' and should receive purchase responses from the UA in the form of asynchronous callbacks.
An OWA should be able to access the in-app web payments services using an API (<code>navigator.mozPay</code>) exposed by the User Agent on the device (for the B2G use case). The UA must use an asynchronous message loop to convey billing requests and responses between the application and the Payment Processor (or Provider). In practice, the applications should never directly communicate with the Payment Processors's servers. Instead, the application should send billing requests to the UA via 'navigator.mozPay()' and should receive purchase responses from the UA in the form of asynchronous callbacks.


== Payment flow overview ==
== Payment flow overview ==
* The app initiates a payment by signing a JWT request and calling <code>navigator.pay()</code>.
* The app initiates a payment by signing a JWT request and calling <code>navigator.mozPay()</code>.
* This starts the buyflow in a content iframe inside a trusted dialog ("chrome dialog").
* This starts the buyflow in a content iframe inside a trusted dialog ("chrome dialog").
* A purchasing flow is served from the Payment Provider's server as an HTML5 document inside the trusted dialog.
* A purchasing flow is served from the Payment Provider's server as an HTML5 document inside the trusted dialog.
Line 39: Line 39:


=== Entities ===
=== Entities ===
; Application: Open Web App which offers digital goods to be sold. OWAs that charge users via <code>navigator.pay()</code> require a client and server side.
; Application: Open Web App which offers digital goods to be sold. OWAs that charge users via <code>navigator.mozPay()</code> require a client and server side.
; BlueVia portal: BlueVia is Telefónica's developer program. Developers can register in BlueVia portal in order to make use of TEF Carrier APIs, such as the payment API. We will be using Telefónica's Payment Provider as an example for the payment flow explanation and BlueVia is part of it.
; BlueVia portal: BlueVia is Telefónica's developer program. Developers can register in BlueVia portal in order to make use of TEF Carrier APIs, such as the payment API. We will be using Telefónica's Payment Provider as an example for the payment flow explanation and BlueVia is part of it.
; Developer: Application developer, seller of digital goods.
; Developer: Application developer, seller of digital goods.
; Mozilla Marketplace:Developer portal and application repository. Developers can submit apps to the Mozilla Marketplace so the users can purchase and download this apps. The Mozilla Marketplace would also be using the <code>navigator.pay</code> function to charge users for application purchases.
; Mozilla Marketplace:Developer portal and application repository. Developers can submit apps to the Mozilla Marketplace so the users can purchase and download this apps. The Mozilla Marketplace would also be using the <code>navigator.mozPay</code> function to charge users for application purchases.
; Payment Provider (or Processor): Offers merchants online services for accepting electronic payments by a variety of payment methods (credict card (CC), direct to bill (D2B), etc.).
; Payment Provider (or Processor): Offers merchants online services for accepting electronic payments by a variety of payment methods (credict card (CC), direct to bill (D2B), etc.).
; TU ID Connect: Telefónica's End user/Customer portal. This customers will be the ones charged for application downloads or in-app purchases.
; TU ID Connect: Telefónica's End user/Customer portal. This customers will be the ones charged for application downloads or in-app purchases.
Line 66: Line 66:
An Application Key and Application Secret (generated by BlueVia) should be assigned and provided to the application developer. The application developer can provide BlueVia (via Mozilla Marketplace app registration) with <code>postback</code> and <code>chargeback</code> URLs (this URLs should be editable via Mozilla Marketplace / BlueVia portal).
An Application Key and Application Secret (generated by BlueVia) should be assigned and provided to the application developer. The application developer can provide BlueVia (via Mozilla Marketplace app registration) with <code>postback</code> and <code>chargeback</code> URLs (this URLs should be editable via Mozilla Marketplace / BlueVia portal).


The application secret will be used by the developer to sign the JWT included with the navigator.pay() function. The developer must save the application key and application secret securely in his app server. He must generate the signed JWT using server-side code.
The application secret will be used by the developer to sign the JWT included with the navigator.mozPay() function. The developer must save the application key and application secret securely in his app server. He must generate the signed JWT using server-side code.


A privileged app registration/edition API is exposed by BlueVia.
A privileged app registration/edition API is exposed by BlueVia.
Line 109: Line 109:
*** '''chargebackURL''': URL where the payment processor sends an HTTP POST message to whenever a refund associated with this transaction is done. If the payment processor stores a different chargeback URL for this application, the one within the JWT should override the stored one.
*** '''chargebackURL''': URL where the payment processor sends an HTTP POST message to whenever a refund associated with this transaction is done. If the payment processor stores a different chargeback URL for this application, the one within the JWT should override the stored one.


* For a user to make a purchase, the app must execute the Javascript method <code>navigator.pay()</code> with this signed payment request. For example, the app might have a 'buy' button that triggers this method when clicked. Then <code>navigator.pay</code> method should take the signed payment JWT or an array of them. As a result of this call a [https://developer.mozilla.org/en/DOM/DOMRequest DOMRequest] object would be returned. The developer may use this DOMRequest object to monitor the progress of the operation.
* For a user to make a purchase, the app must execute the Javascript method <code>navigator.mozPay()</code> with this signed payment request. For example, the app might have a 'buy' button that triggers this method when clicked. Then <code>navigator.mozPay</code> method should take the signed payment JWT or an array of them. As a result of this call a [https://developer.mozilla.org/en/DOM/DOMRequest DOMRequest] object would be returned. The developer may use this DOMRequest object to monitor the progress of the operation.
  <code>
  <code>
  let request = navigator.pay([signedJWT1, signedJWTn]);
  let request = navigator.mozPay([signedJWT1, signedJWTn]);
  request.onsuccess = function () {
  request.onsuccess = function () {
   [...]
   [...]
Line 119: Line 119:
  }
  }
  </code>
  </code>
* The <code>navigator.pay</code> method must open a Payment Provider selection screen based on the received JWTs, so the user can choose the payment method that is more appropriate for him. B2G would only show the payment providers for the JWT '''typ''' values that are pre-registered in the UA. JWTs containing a '''typ''' value not registered in the UA would be considered as invalid.
* The <code>navigator.mozPay</code> method must open a Payment Provider selection screen based on the received JWTs, so the user can choose the payment method that is more appropriate for him. B2G would only show the payment providers for the JWT '''typ''' values that are pre-registered in the UA. JWTs containing a '''typ''' value not registered in the UA would be considered as invalid.
* Once the user selects a Payment Provider the UA must open a trusted dialog ("chrome" dialog) containing the Payment Provider's buy flow that is registered in the UA for the '''typ''' value of the passed JWT (TU ID Connect in case of BlueVia).
* Once the user selects a Payment Provider the UA must open a trusted dialog ("chrome" dialog) containing the Payment Provider's buy flow that is registered in the UA for the '''typ''' value of the passed JWT (TU ID Connect in case of BlueVia).
* User authentication can be done via network authentication (MSISDN) or BrowserID assertion. Authorization could also be done with user password or PIN code sent via SMS.
* User authentication can be done via network authentication (MSISDN) or BrowserID assertion. Authorization could also be done with user password or PIN code sent via SMS.
Line 158: Line 158:
''(This is just a proposal and not the current Marketplace scenario)''
''(This is just a proposal and not the current Marketplace scenario)''


The Mozilla Marketplace use <code>navigator.pay</code> to execute purchase transactions for apps. The only difference to in-app payments is that the Marketplace use the app as the issuer (recipient of funds), instead of itself.
The Mozilla Marketplace use <code>navigator.mozPay</code> to execute purchase transactions for apps. The only difference to in-app payments is that the Marketplace use the app as the issuer (recipient of funds), instead of itself.


Once the user starts an application purchase process, the marketplace generates a payment request that contains all the information about the application being purchased: price, currency, name, description and so on, with the addition of the '''application key''' that identifies the '''developer''' as issuer of the transaction (recipient of funds) and the marketplace '''postback''' and '''chargeback''' URLs, so the '''Marketplace''' could receive notifications about the transaction result or refunds associated with the transaction. The marketplace signs the payment request with the application secret.
Once the user starts an application purchase process, the marketplace generates a payment request that contains all the information about the application being purchased: price, currency, name, description and so on, with the addition of the '''application key''' that identifies the '''developer''' as issuer of the transaction (recipient of funds) and the marketplace '''postback''' and '''chargeback''' URLs, so the '''Marketplace''' could receive notifications about the transaction result or refunds associated with the transaction. The marketplace signs the payment request with the application secret.
Line 187: Line 187:


=== Refunds for in-app purchases ===
=== Refunds for in-app purchases ===
The <code>navigator.pay</code> API allows refunds the same way as it allow purchases, so the developer has the choice of exposing a way to request refunds from his application. The difference between a purchase and a refund is within the JWT request parameters. The content of this refund requests depend on the needs of the Payment Provider. For the BlueVia case, a ''transaction ID'', a ''reason'' and an optional ''chargeback URL'' parameters are required.
The <code>navigator.mozPay</code> API allows refunds the same way as it allow purchases, so the developer has the choice of exposing a way to request refunds from his application. The difference between a purchase and a refund is within the JWT request parameters. The content of this refund requests depend on the needs of the Payment Provider. For the BlueVia case, a ''transaction ID'', a ''reason'' and an optional ''chargeback URL'' parameters are required.
<code>
<code>
   {
   {
Line 230: Line 230:
More details about the chargeback notifications are explained in the [https://wiki.mozilla.org/WebAPI/WebPayment#Notifications Notifications] section.
More details about the chargeback notifications are explained in the [https://wiki.mozilla.org/WebAPI/WebPayment#Notifications Notifications] section.


Apart from the <code>navigator.pay()</code> option for requesting refunds, the Payment Processor (BlueVia) '''SHOULD''' keep a list of transactions accessible via user profile, allowing the user to cancel the latest ones. A chargeback notification should be sent to the developer once a refund is requested by the user and executed by the Payment Processor systems. The way the developer handles the chargeback notification would depend on the nature of the sold digital good and it is developer's responsibility to cancel or remove it properly from the user's device. Go to [https://developer.mozilla.org/en-US/docs/Apps/Validating_a_receipt Validating a receipt] for information about how the Mozilla Marketplace deals with apps receipts.
Apart from the <code>navigator.mozPay()</code> option for requesting refunds, the Payment Processor (BlueVia) '''SHOULD''' keep a list of transactions accessible via user profile, allowing the user to cancel the latest ones. A chargeback notification should be sent to the developer once a refund is requested by the user and executed by the Payment Processor systems. The way the developer handles the chargeback notification would depend on the nature of the sold digital good and it is developer's responsibility to cancel or remove it properly from the user's device. Go to [https://developer.mozilla.org/en-US/docs/Apps/Validating_a_receipt Validating a receipt] for information about how the Mozilla Marketplace deals with apps receipts.


=== Marketplace refunds for application purchases ===
=== Marketplace refunds for application purchases ===
Line 236: Line 236:
The way the Marketplace would handle the refund requests from the user would depend on the Payment Provider used for each specific transaction. Currently, the Marketplace is supporting two different Payment Providers: PayPal and Telefónica BlueVia. The PayPal case is out of the scope of this document.
The way the Marketplace would handle the refund requests from the user would depend on the Payment Provider used for each specific transaction. Currently, the Marketplace is supporting two different Payment Providers: PayPal and Telefónica BlueVia. The PayPal case is out of the scope of this document.


For the BlueVia use case, in order to request refunds for application purchases the Marketplace would use the <code>navigator.pay</code> API. Just like for the Marketplace payment flow via BlueVia Payment Provider, the only difference to in-app refunds is that the Marketplace use the app as the issuer, instead of itself.
For the BlueVia use case, in order to request refunds for application purchases the Marketplace would use the <code>navigator.mozPay</code> API. Just like for the Marketplace payment flow via BlueVia Payment Provider, the only difference to in-app refunds is that the Marketplace use the app as the issuer, instead of itself.


Once the user requests a refund for an application purchased, the Marketplace generates a refund request that contains the transactionID returned as result of the payment flow for that application. The marketplace can also add a chargeback URL, so it could receive notifications about the refund process result in this URL. The new chargeback URL is optional and you may found more info about this in the [https://wiki.mozilla.org/WebAPI/WebPayment#Notifications Notifications] section. Finally, the marketplace should sign the refund request with the application secret.
Once the user requests a refund for an application purchased, the Marketplace generates a refund request that contains the transactionID returned as result of the payment flow for that application. The marketplace can also add a chargeback URL, so it could receive notifications about the refund process result in this URL. The new chargeback URL is optional and you may found more info about this in the [https://wiki.mozilla.org/WebAPI/WebPayment#Notifications Notifications] section. Finally, the marketplace should sign the refund request with the application secret.
Line 270: Line 270:


=== Marketplace notifications ===
=== Marketplace notifications ===
As you already know, the Marketplace would use the <code>navigator.pay()</code> to request payments and refunds as any other developer would. The main difference is that the Marketplace would request payments and refunds on behalf of the developer. So it would need to add the appID on its payment and refund requests to identify the developer.
As you already know, the Marketplace would use the <code>navigator.mozPay()</code> to request payments and refunds as any other developer would. The main difference is that the Marketplace would request payments and refunds on behalf of the developer. So it would need to add the appID on its payment and refund requests to identify the developer.


Besides that, as the Marketplace wants to be notified about app purchases and refunds related to that purchases, it would need to use option 2 mentioned before. That means, it would need to include it postback and chargeback URL, so the Payment Provider would notify the Marketplace instead of the developer. Once the Marketplace is notified by the Payment Provider, it would need to notify the developer via the default URL that he might have provided.
Besides that, as the Marketplace wants to be notified about app purchases and refunds related to that purchases, it would need to use option 2 mentioned before. That means, it would need to include it postback and chargeback URL, so the Payment Provider would notify the Marketplace instead of the developer. Once the Marketplace is notified by the Payment Provider, it would need to notify the developer via the default URL that he might have provided.
Line 294: Line 294:
== See also ==
== See also ==
* [https://docs.google.com/document/d/1NLKbHVPQXa9uvDBC3cfgOD7sIrtIxi0qDoXMQrxcCsI/edit First draft]
* [https://docs.google.com/document/d/1NLKbHVPQXa9uvDBC3cfgOD7sIrtIxi0qDoXMQrxcCsI/edit First draft]
* [https://wiki.mozilla.org/Security/Reviews/navigator.pay Security review]
* [https://wiki.mozilla.org/Security/Reviews/navigator.mozPay Security review]
* [https://docs.google.com/document/d/1EBkzFye6DqCQkMEkXkjLjMvaYYCqvCGJrYhyG38R4DU/edit#heading=h.q13jnkaxpfle Threat model]
* [https://docs.google.com/document/d/1EBkzFye6DqCQkMEkXkjLjMvaYYCqvCGJrYhyG38R4DU/edit#heading=h.q13jnkaxpfle Threat model]
* [https://developer.mozilla.org/en/Apps/In-app_payments Marketplace In-app payments proposal]
* [https://developer.mozilla.org/en/Apps/In-app_payments Marketplace In-app payments proposal]
Confirmed users
483

edits