Episode 554: Web Reception, But No Card Information

Sunday, September 24, 2017

Operation: Acceptance of credit card registration

Want to promote credit card charging...

If I could charge to "credit cards" according to the service usage record automatically, very smooth settlement would be possible. If I could digitize "bill issuance", I would drastically reduce cost on payment collection.

I would like to prepare a "card payment system" like an electric company, gas company, or mobile phone company.

Challenge: Risk of credit card information data breach

However, as security requirements become more stringent, "holding a credit card number" seems to be a big risk.

Our company is not a power company nor, a big company such as Google or Facebook. In other words, it seems that we unlikely could comply the requirement that "PCI DSS" says. "What important is," the credit companies (Acquirer) say, "not to possess cardholder's info".

Alright, I'm going to leave cardholder's info such as PAN, PIN, CVC, to "Payment agencies", as it is advocated in a document by the Japanese government that "we aim for non-retention by March 2018". (But how?)
  • PAN:Primary Account Number (card number)
  • PIN:Personal Identification Number
  • CVC: Card Verification Code/Value (3 digit number. Formally CVC2, aka CID)
* Reference: PCI DSS (PAYMENT CARD INDUSTRY
DATA SECURITY STANDARD) Ver.3.2 2016-04
* Reference: Payment services (PSD 2) - Directive (EU) 2015/2366

[Credit Card Info Reception]

Solution: Browser based Tokenization

If you place a "Form Start Event" at the beginning of a Workflow, it will automatically start when there is an entry in the publicated Web form.

In this example, once a customer completes "Input of application for service", "Application reception flow" in the company is automatically started. It is noteworthy that "credit card number etc" will never be delivered to the Workflow system.

Specifically, customer's "card information etc." is tokenized by JavaScript communication (CORS communication) between customer's browser and Stripe.com, and only the token information is transmitted to the Workflow system . (Employees involved in reception process never see credit card information.)

※ I am going to introduce charging-fee operation in the next article.

Discussion: Difficulty of JavaScript implementation

The mechanism of sending card information from [Customer's browser] directly to [Payment Service Provider] (PSP) without passing through [Member Store Server] is very effective for "realizing non-retention". In this example, "card information etc." is entrusted to Stripe.com, and a token as its storage ID flows in the Workflow.

Although so-called "Cross-domain access" is required, Stripe.com has been supporting CORS since 2012 (W3C Candidate Recommendation in Jan. 2013, Recommendation in Jan. 2014).

* Incidentally, Stripe.com has two tokenization mechanisms called "Checkout" (embedded payment form) and "Elements" (pre-built UI components). We use "Elements" which has higher degree of freedom, in order to customize "Form Start Event" here.


On the other hand, in the cloud-based Workflow "Questetra BPM Suite", it is possible to decorate the "Operation form screen" (including the Form Start screen) with HTML / JavaScript. (M213)

However (at least as of v11.4), these codes are inserted into the <body> of the HTML document. That is, if you want to use the function defined in the external .js file, you need programming for "dynamic loading". For example, in the case of using jQuery, "JS file load completion" is guaranteed by the method of setting the callback function as the second argument of getScript ().


Setting example in &#91;Guid Panel&#93;
jQuery.getScript("https://js.stripe.com/v3/", function(){
  var stripe = Stripe('pk_test_6pRNASCoBOKtIshFeQd4XMUh'); // Create a Stripe client
  var elements = stripe.elements(); // Create an instance of Elements
  var card = elements.create('card', { hidePostalCode: true, style: {
    base: {
      iconColor: '#666EE8',
      color: '#31325F',
      lineHeight: '30px',
      fontWeight: 300,
      fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
      fontSize: '14px',
      '::placeholder': {
        color: '#CFD7E0',
      }
    },
    invalid: {
      color: '#fa755a',
      iconColor: '#fa755a'
    }
  }
});
card.mount('#card-element');

//// Handle real-time validation errors from the card Element
card.addEventListener('change', function(event) {
  var displayError = document.getElementById('carderror');
  if (event.error) { displayError.textContent = event.error.message;
  } else { displayError.textContent = ''; }
});


//////// Tokenize with Button Click
var tokenizeButton = document.getElementById('stripeTokenization');
tokenizeButton.addEventListener('click', function(event) {
  var extraDetails = {
    name: jQuery('input[name=cardholder-name]').val(),
  };
  stripe.createToken(card, extraDetails).then(function(result) {
    if (result.error) {
      // Inform the user if there was an error
      var errorElement = document.getElementById('carderror');
      errorElement.textContent = result.error.message;
    } else {
      jQuery("input[name='data\\[6\\].input']").val( result.token.id );
      jQuery("input[name='data\\[7\\].input']").val( result.token.card.last4 );
      var successElement = document.getElementById('cardsuccess');
      successElement.textContent = "Your Stripe token for use of Questetra is generated! : " + result.token.id;
    }
  });
});

}); // endof "jQuery.getScript( , function(){"

jQuery('input[name="data\\[6\\].input"]').attr( "readonly", true );
jQuery('input[name="data\\[7\\].input"]').attr( "readonly", true );
jQuery('input[name="data\\[6\\].input"]').css( "background-color", "#f2f2f2" );
jQuery('input[name="data\\[7\\].input"]').css( "background-color", "#f2f2f2" );

</script>

<div class="stripegroup">
  <label class="stripebox">
    <span>Cardholder</span>
    <input name="cardholder-name" class="field" placeholder="Jane Doe" />
  </label>
  <label class="stripebox">
    <span>CardNum</span>
    <div id="card-element" class="field"></div>
  </label>

  <div class="outcome">
    <div id="carderror" role="alert"></div>
  </div>

  <button type="button" id="stripeTokenization">Tokenization</button>
  <div id="stripenote"> * Tokenized by Stripe.com, your credit card details will Not be submitted to Questetra.</div>

  <div class="outcome">
    <div id="cardsuccess"></div>
  </div>
</div>

<Form screen>

[Data Items list]


[Free download]
&lt;Similar Models&gt;
&lt;&lt;Related Articles&gt;&gt;

[Japanese Entry (ε’Œζ–‡θ¨˜δΊ‹)]