samkelleher / cordova-plugin-applepay

A complete Cordova plugin that adds Apple Pay support.
Apache License 2.0
47 stars 63 forks source link

How to process Base64 token on ApplePay.makePaymentRequest(order) ? #48

Open websitedesignanddeveloper opened 5 years ago

websitedesignanddeveloper commented 5 years ago

I'm trying to implement the Apple Pay with ionic, Everything works fine. Apple Pay drop in sheet comes with payment info. On makePaymentRequest method I do get the Base64 token, But I have no idea, how to process this token, Because at server level like stripe they except token starting from something like this tok_19GCAQI5NuVQgnjeKNE32K0p . But One I am getting is completely different. On decoding this base64 token, This JSON object I get.

{ "type" : "applepay", "token_data" : { "version":"EC_v1", "data":"PxiLne-........", "signature":"........", "header":{ "ephemeralPublicKey":"MFkwE..............", "publicKeyHash":"MZ78V........", "transactionId":"ee44abfeaeeccd7663........" } } }

Please help how I can process this payment. Need token to charge to client. I'm using stripe at backend processing.

adamduren commented 5 years ago

I reverse engineered the iOS SDK method for creating a token and came up with this to create a token.

// Reverse Engineered from
// https://github.com/stripe/stripe-ios/blob/d4e3170fab9ab940816ea28ea8084b48a842e764/Stripe/STPAPIClient%2BApplePay.m#L22-L28
class StripeToken {
  // IPaymentResponse is the response from `makePayment()`
  public async getTokenFromPaymentData(payment: IPaymentResponse) {
    const payload: any = {
      pk_token: atob(payment.paymentData),
      ...this.addressParamsFromPaymentData(payment),
    };

    if (payment.paymentMethodDisplayName) {
      payload.pk_token_instrument_name = payment.paymentMethodDisplayName;
    }

    if (payment.paymentMethodNetwork) {
      payload.pk_token_payment_network = payment.paymentMethodNetwork;
    }

    if (payment.transactionIdentifier) {
      payload.pk_token_transaction_id = payment.transactionIdentifier;
    }

    const response = await fetch('https://api.stripe.com/v1/tokens', {
      method: 'POST',
      headers: {
        'Stripe-Version': '2015-10-12',
        Authorization: `Bearer ${environment.stripePublishableKey}`,
      },
      body: new URLSearchParams(payload),
    });

    const data = await response.json();
    const token = data.id;

    return token;
  }

  private addressParamsFromPaymentData(payment: IPaymentResponse) {
    if (payment.billingNameFirst) {
      const params: any = {};

      if (payment.billingNameFirst) {
        params['card[name]'] = `${payment.billingNameFirst}${
          payment.billingNameLast ? ' ' + payment.billingNameLast : ''
        }`;      }

      if (payment.billingAddressStreet) {
        params['card[address_line1]'] = payment.billingAddressStreet;
        params['card[address_city]'] = payment.billingAddressCity;
        params['card[address_state]'] = payment.billingAddressState;
        params['card[address_zip]'] = payment.billingPostalCode;
        params['card[address_country]'] = payment.billingCountry;
      }

      return params;
    } else {
      return null;
    }
  }
}
arashcy commented 5 years ago

creating a token

How does your response relate to what he's asking?

dolosplus commented 4 years ago

I'm having the same problem. The response I see when tapping on the Payment button, I get:

 {
     "paymentMethodNetwork":"Visa",
     "paymentMethodDisplayName":"Visa 1234",
     "paymentData":"eyJ2ZXJ....",
     "paymentMethodTypeCard":"debit",
     "transactionIdentifier":"F28...."
}

I'm trying to debug the plugin code and I only see the encrypted paymentData which is different than the Apple documentation with this structure:

{
"type" : "applepay",
"token_data" : {
"version":"EC_v1",
"data":"PxiLne-........",
"signature":"........",
"header":{
"ephemeralPublicKey":"MFkwE..............",
"publicKeyHash":"MZ78V........",
"transactionId":"ee44abfeaeeccd7663........"
}
}
}

So with this plugin, how do I supposed to get ephemeralPublicKey, publicKeyHash etc? Unless i'm missing something.

Dhineshdx commented 4 years ago

@dolosplus All you need is to decode base64 paymentData from the response. If you decode it you will have the { "version": "EC_v1", "data": "*********", "signature": "*********", "header": { "ephemeralPublicKey": "*********", "publicKeyHash": "*************", "transactionId": "************" } }