Credit Card Processing

Discussions relating to Jiwa 7 plugin development, and the Jiwa 7 API.

Re: Credit Card Processing

Postby pricerc » Mon Jan 31, 2022 3:46 pm

Mike.Sheen wrote:
pricerc wrote:I seem to have the "New" version. Does this mean the existing plugin won't work?


Don't know - if you can't get it working, create a helpdesk ticket and we'll go through the motions and see if we can get it working, and perhaps explore alternatives.


Have raised a ticket.

Also just been looking at Stripe, which has a much cleaner API. And helpful videos.

There is also a ServiceStack Stripe API which I'm going to look at presently. It's all of one C# file, and since y'all have ServiceStack built into Jiwa, the ServiceStack.Text and ServiceStack.API references will be there. I'm thinking I can add the file as its own plugin, and then use it as a plugin reference in my own code. That way, updates to the original code can be pasted straight in without needing to be merged.
/Ryan

ERP Consultant,
Advanced ERP Limited, NZ
https://aerp.co.nz
User avatar
pricerc
Senpai
Senpai
 
Posts: 518
Joined: Mon Aug 10, 2009 12:22 pm
Location: Auckland, NZ
Topics Solved: 21

Re: Credit Card Processing

Postby Mike.Sheen » Mon Jan 31, 2022 5:07 pm

pricerc wrote:Have raised a ticket.

Also just been looking at Stripe, which has a much cleaner API. And helpful videos.

There is also a ServiceStack Stripe API which I'm going to look at presently. It's all of one C# file, and since y'all have ServiceStack built into Jiwa, the ServiceStack.Text and ServiceStack.API references will be there. I'm thinking I can add the file as its own plugin, and then use it as a plugin reference in my own code. That way, updates to the original code can be pasted straight in without needing to be merged.


I remember looking at Stripe when we were first looking at incorporating ServiceStack for our REST API - the idea surfaced then that this would be a good API to use for payment processing in Jiwa because 1) It was a clean, well thought out API 2) It does things exactly as you would expect.

I especially liked that you create a customer in Stripe and create cards for customers also in Stripe, so you don't ever store the customer card details in Jiwa. This is the way.
Mike Sheen
Chief Software Engineer
Jiwa Financials

If I do answer your question to your satisfaction, please mark it as the post solving the topic so others with the same issue can readily identify the solution
User avatar
Mike.Sheen
Overflow Error
Overflow Error
 
Posts: 2583
Joined: Tue Feb 12, 2008 11:12 am
Location: Perth, Republic of Western Australia
Topics Solved: 807

Re: Credit Card Processing

Postby pricerc » Tue Feb 01, 2022 9:22 am

Mike.Sheen wrote:I especially liked that you create a customer in Stripe and create cards for customers also in Stripe, so you don't ever store the customer card details in Jiwa. This is the way.


You can still do this, but it's a little more involved than just creating a card for a customer.

You used to be able to pass in the JSON for a customer with embedded card details and/or add a new card to a customer:
Code: Select all
{
  "email": "[email protected]",
  "source": {
    "object": "card",
    "cvc": "***",
    "exp_month": "12",
    "exp_year": "2027",
    "number": "************0008"
  }
}


This is no longer possible, you get this this back from Stripe:
Code: Select all
{
  "error": {
    "message": "Sending credit card numbers directly to the Stripe API is generally unsafe. We suggest you use test tokens that map to the test card you are using, see https://stripe.com/docs/testing.",
    "type": "invalid_request_error"
  }
}


Now, you need to create a "payment method" (which to be fair, in Australia includes BECS debit), for which you get a payment method 'id'. You then, in a separate transaction, attach that payment method id to a customer.

The Stripe developer page helpfully provides all the raw API data in a log for analysis (roughly):
Code: Select all
POST   /v1/customers
{
  "email": "[email protected]"
}
--------------------
Response body
{
  "id": "cus_L44O8GxGWoae5j",
  "object": "customer",
  ...
==============

POST   /v1/payment_methods
{
  "card": {
    "cvc": "***",
    "exp_month": "12",
    "exp_year": "2027",
    "number": "************0008"
  },
  "type": "card"
}
--------------------
Response body
{
  "id": "pm_1KNwhyBWzF2Y28hVhqoKS1Y2",
  "object": "payment_method",
  ...
==============
 
POST   /v1/payment_methods/pm_1KNwhyBWzF2Y28hVhqoKS1Y2/attach
{
  "customer": "cus_L44O8GxGWoae5j"
}
--------------------
Response body
{
  "id": "pm_1KNwhyBWzF2Y28hVhqoKS1Y2",
  "object": "payment_method",
  ...
  "card": {
   ...
    "country": "NZ",
    "exp_month": 12,
    "exp_year": 2027,
   ...
    "last4": "0008",
   ...
  },
  ...
  "customer": "cus_L44O8GxGWoae5j",
  ...
  "type": "card"
}
==============



Now I'm trying to work out how to charge them...
/Ryan

ERP Consultant,
Advanced ERP Limited, NZ
https://aerp.co.nz
User avatar
pricerc
Senpai
Senpai
 
Posts: 518
Joined: Mon Aug 10, 2009 12:22 pm
Location: Auckland, NZ
Topics Solved: 21

Re: Credit Card Processing

Postby pricerc » Thu Feb 03, 2022 9:05 pm

Turns out you can attach a card to a customer, just takes more than one step.... while technically 'deprecated' Stripe claim to have no plans to remove it.

It is only good for assigning a single card to a customer, but that's ok for most use-cases.

Code: Select all
        static void AddCustomerAndSource()
        {
            StripeConfiguration.ApiKey = APIKey;

            var customerService = new CustomerService();
            var customer = customerService.Create(new CustomerCreateOptions()
            {
                Email = customerEmail,
            });

            var scs = new SourceService();
            var sc = scs.Create(new SourceCreateOptions()
            {
                Type = "card",
                Card = new SourceCardOptions()
                {
                    Number = cardNumber,
                    ExpYear = expYear,
                    ExpMonth = expMonth,
                    Cvc = cvc,
                }
            });

            customer = customerService.Update(customer.Id, new CustomerUpdateOptions()
            {
                Source = sc.Id,
            });

            Console.WriteLine(customer.ToJson());
        }



With this legacy API, you can also still make ad-hoc payments without creating a customer first
Code: Select all
        private static void SimpleCharge()
        {
            StripeConfiguration.ApiKey = APIKey;

            var transationKey = DateTime.UtcNow.ToString("yyMMddHHmm");

            var tokenOptions = new TokenCreateOptions()
            {
                Card = new TokenCardOptions()
                {
                    Number = cardNumber,
                    ExpYear = expYear,
                    ExpMonth = expMonth,
                    Cvc = cvc,
                },
            };

            var tokenService = new TokenService();

            var tokenRequestOptions = new RequestOptions() { IdempotencyKey = transationKey + "token", };
            var token = tokenService.Create(tokenOptions, tokenRequestOptions);

            var chargeOptions = new ChargeCreateOptions()
            {
                Amount = 101,
                Currency = "NZD",
                Source = token.Id,
            };

            var chargeService = new ChargeService();
            var chargeRequestOptions = new RequestOptions() { IdempotencyKey = transationKey + "charge", };
            try
            {
                var charge = chargeService.Create(chargeOptions, chargeRequestOptions);

                Console.WriteLine(charge.ToJson());
            }
            catch (StripeException ex)
            {
                Console.WriteLine(ex.StripeError.ToJson());
            }
        }


I'm starting with ad-hoc payments in my plugin (to replace what we have now), leaving space to switch to creating Stripe customers for Jiwa debtors later on.
/Ryan

ERP Consultant,
Advanced ERP Limited, NZ
https://aerp.co.nz
User avatar
pricerc
Senpai
Senpai
 
Posts: 518
Joined: Mon Aug 10, 2009 12:22 pm
Location: Auckland, NZ
Topics Solved: 21

Previous

Return to Technical and or Programming

Who is online

Users browsing this forum: No registered users and 3 guests