B2G/gecko/dom/payment/Payment.jsm
/**
   * Process a message from the content process.
   */
Process a message from the content process.
Process a message from the content process .
function receiveMessage(aMessage) {
    let name = aMessage.name;
    let msg = aMessage.json;
    debug("Received '" + name + "' message from content process");
    switch (name) {
      case "Payment:Pay": {
        if (!this.registeredProviders) {
          this.registeredProviders = {};
          this.registerPaymentProviders();
        }
        let requestId = msg.requestId;
        this.messageManagers[requestId] = aMessage.target;
        let paymentRequests = [];
        let jwtTypes = [];
        for (let i in msg.jwts) {
          let pr = this.getPaymentRequestInfo(requestId, msg.jwts[i]);
          if (!pr) {
            continue;
          }
          if (!(pr instanceof Ci.nsIDOMPaymentRequestInfo)) {
            return;
          }
          if (jwtTypes[pr.type]) {
            this.paymentFailed(requestId,
                               "PAY_REQUEST_ERROR_DUPLICATED_JWT_TYPE");
            return;
          }
          jwtTypes[pr.type] = true;
          paymentRequests.push(pr);
        }
        if (!paymentRequests.length) {
          this.paymentFailed(requestId,
                             "PAY_REQUEST_ERROR_NO_VALID_REQUEST_FOUND");
          return;
        }
        let glue = Cc["@mozilla.org/payment/ui-glue;1"]
                   .createInstance(Ci.nsIPaymentUIGlue);
        if (!glue) {
          debug("Could not create nsIPaymentUIGlue instance");
          this.paymentFailed(requestId,
                             "INTERNAL_ERROR_CREATE_PAYMENT_GLUE_FAILED");
          return;
        }
        let confirmPaymentSuccessCb = function successCb(aRequestId,
                                                         aResult) {
          let selectedProvider = this.registeredProviders[aResult];
          if (!selectedProvider || !selectedProvider.uri) {
            debug("Could not retrieve a valid provider based on user's " +
                  "selection");
            this.paymentFailed(aRequestId,
                               "INTERNAL_ERROR_NO_VALID_SELECTED_PROVIDER");
            return;
          }
          let jwt;
          for (let i in paymentRequests) {
            if (paymentRequests[i].type == aResult) {
              jwt = paymentRequests[i].jwt;
              break;
            }
          }
          if (!jwt) {
            debug("The selected request has no JWT information associated");
            this.paymentFailed(aRequestId,
                               "INTERNAL_ERROR_NO_JWT_ASSOCIATED_TO_REQUEST");
            return;
          }
          this.showPaymentFlow(aRequestId, selectedProvider, jwt);
        };
        let confirmPaymentErrorCb = this.paymentFailed;
        glue.confirmPaymentRequest(requestId,
                                   paymentRequests,
                                   confirmPaymentSuccessCb.bind(this),
                                   confirmPaymentErrorCb.bind(this));
        break;
      }
      case "Payment:Success":
      case "Payment:Failed": {
        let mm = this.messageManagers[msg.requestId];
        mm.sendAsyncMessage(name, {
          requestId: msg.requestId,
          result: msg.result,
          errorMsg: msg.errorMsg
        });
        break;
      }
    }
  }
function receiveMessage ( aMessage ) { let name = aMessage . name ; let msg = aMessage . json ; debug ( "Received '" + name + "' message from content process" ) ; switch ( name ) { case "Payment:Pay" : { if ( ! this . registeredProviders ) { this . registeredProviders = { } ; this . registerPaymentProviders ( ) ; } let requestId = msg . requestId ; this . messageManagers [ requestId ] = aMessage . target ; let paymentRequests = [ ] ; let jwtTypes = [ ] ; for ( let i in msg . jwts ) { let pr = this . getPaymentRequestInfo ( requestId , msg . jwts [ i ] ) ; if ( ! pr ) { continue ; } if ( ! ( pr instanceof Ci . nsIDOMPaymentRequestInfo ) ) { return ; } if ( jwtTypes [ pr . type ] ) { this . paymentFailed ( requestId , "PAY_REQUEST_ERROR_DUPLICATED_JWT_TYPE" ) ; return ; } jwtTypes [ pr . type ] = true ; paymentRequests . push ( pr ) ; } if ( ! paymentRequests . length ) { this . paymentFailed ( requestId , "PAY_REQUEST_ERROR_NO_VALID_REQUEST_FOUND" ) ; return ; } let glue = Cc [ "@mozilla.org/payment/ui-glue;1" ] . createInstance ( Ci . nsIPaymentUIGlue ) ; if ( ! glue ) { debug ( "Could not create nsIPaymentUIGlue instance" ) ; this . paymentFailed ( requestId , "INTERNAL_ERROR_CREATE_PAYMENT_GLUE_FAILED" ) ; return ; } let confirmPaymentSuccessCb = function successCb ( aRequestId , aResult ) { let selectedProvider = this . registeredProviders [ aResult ] ; if ( ! selectedProvider || ! selectedProvider . uri ) { debug ( "Could not retrieve a valid provider based on user's " + "selection" ) ; this . paymentFailed ( aRequestId , "INTERNAL_ERROR_NO_VALID_SELECTED_PROVIDER" ) ; return ; } let jwt ; for ( let i in paymentRequests ) { if ( paymentRequests [ i ] . type == aResult ) { jwt = paymentRequests [ i ] . jwt ; break ; } } if ( ! jwt ) { debug ( "The selected request has no JWT information associated" ) ; this . paymentFailed ( aRequestId , "INTERNAL_ERROR_NO_JWT_ASSOCIATED_TO_REQUEST" ) ; return ; } this . showPaymentFlow ( aRequestId , selectedProvider , jwt ) ; } ; let confirmPaymentErrorCb = this . paymentFailed ; glue . confirmPaymentRequest ( requestId , paymentRequests , confirmPaymentSuccessCb . bind ( this ) , confirmPaymentErrorCb . bind ( this ) ) ; break ; } case "Payment:Success" : case "Payment:Failed" : { let mm = this . messageManagers [ msg . requestId ] ; mm . sendAsyncMessage ( name , { requestId : msg . requestId , result : msg . result , errorMsg : msg . errorMsg } ) ; break ; } } }
Process a message from the content process.
Process a message from the content process .
// First of all, we register the payment providers. // We save the message target message manager so we can later dispatch // back messages without broadcasting to all child processes. // We check the jwt type and look for a match within the // registered payment providers to get the correct payment request // information. // We consider jwt type repetition an error. // After getting the list of valid payment requests, we ask the user // for confirmation before sending any request to any payment provider. // If there is more than one choice, we also let the user select the one // that he prefers. // Get the appropriate payment provider data based on user's choice.