Search code examples
web-applicationsstripe-paymentscredit-cardpayment-processingstripe-connect

Any way to accept Credit Card swipes with a reader from a non-native Web App?


I am working on an application that is a marketplace of sorts and using Stripe's API for subscriptions, etc.

The application is a web application that will be used a large amount of the time on mobile devices but it is not native - it is a browser based app.

The end users will need to accept payments from their customers in person and I am trying to find a solution to do so by swiping the customer's card. However all the technology solutions I find (things like Cardflight, etc.) are specifically for native applications (iOS or Android).

Has anyone heard or or done this on a web app?


Solution

  • IfTrue, I went through the same issue (as shown by my comment earlier this year). I figured out how to do this but not without it's disadvantages (security, PCI, etc..). First off, I needed a way in Javascript to trigger events based on swiping, scanning, etc. I found this library, https://github.com/CarlRaymond/jquery.cardswipe, which gives you javascript callbacks (scan complete, scan success, and scan error) tied to scanning events. What I especially liked about it was that you didn't have to focus on the form to have the swiped data go where it needs to go, you can simply select the form and regardless of where you are in the app, it will fill that form out. Again, the author warns about possible security risks in his README file.

    Once I had the parsed credit card scan data, I used stripes jquery.payments library, which provides you functions to validate data as well as build your own forms using inputs. The key was being able to use actually form inputs so I could assign the value of the parsed data to each input before form submission. http://stripe.github.io/jquery.payment/example/

    Stripe has been trying to move away from doing this this way. They aren't keen on people building their own form inputs because of the PCI issues and other related security issues. I ultimately ended up not doing this because I didnt want to be liable for additional PCI regulations. Also, with those basic USB swipers (what I was using), someone could technically intercept the data. This is the only way I know how to do it, and it worked great and I would still be using it if it weren't for the security issues. Here is some of my code. Hope this helps.

                var complete = function(data) {
                    if (data.type == "generic") {
                        sweetAlert("Oops...", "Card Type Not Recognized!", "error");
                        return false;
                    }
                    $("#cc-fullname").val(data.firstName + " " + data.lastName);
                    $("#cc-number").val(data.account);
                    $("#cc-exp").val(data.expMonth + " / " + data.expYear);
    
                    window["stripe_fullname"] = data.firstName + " " + data.lastName;
                    window["stripe_number"] = data.account;
                    window["stripe_exp_month"] = data.expMonth;
                    window["stripe_exp_year"] = data.expYear;
                };
                var failure = function() {
                    swal("Oops...", "Something went wrong... Please try again!", "error");
                }
    
                /*  Success Function
                ========================================= */
                var success = function(event, data) {
                    Stripe.setPublishableKey("{{ stripe_publishable_key }}");
    
    
                    /*  Create Token
                    ======================= */
                    Stripe.card.createToken({
                        name: window["stripe_fullname"],
                        number: window["stripe_number"],
                        exp_month: window["stripe_exp_month"],
                        exp_year: window["stripe_exp_year"],
                    }, stripeResponseHandler);
    
    
                    /*  Response Callback
                    ======================== */
                    function stripeResponseHandler(status, response) {
                        var $form = $('#payment-card-form');
                        if (response.error) {
                            $form.find('.payment-errors').text(response.error.message);
                            $form.find('button').prop('disabled', false);
                        } else {
                            var token = response.id;
                            $form.append($('<input type="hidden" name="stripeToken" />').val(token));
                            $form.get(0).submit();
                        }
                    }
    
    
                }
    
                $.cardswipe({
                    firstLineOnly: true,
                    success: complete,
                    parsers: ["visa", "amex", "mastercard", "discover", "generic"],
                    debug: false
                });
                $(document).on("success.cardswipe", success).on("failure.cardswipe", failure);