How to implement payment intent api? - swift4

So the EU changed a bunch of rules for payments and because of that I am required to use Stripes Payment API, but there is one thing that I'm stuck on. I have been using firebase functions as my backend. So the question is. what exactly is "MyAPIClient"? (see code)
MyAPIClient.createPaymentIntent(amount: 100, currency: "usd") { result
in
switch (result) {
case .success(let clientSecret):
// Hold onto clientSecret for Step 4
case .failure(let error):
// Handle the error
}
}

MyAPIClient is a class defined in one of Stripe's iOS examples to handle HTTP requests between your Application and a server backend. There's a corresponding iOS backend example. If you are using Firebase instead of your own server, you could define server side routes in terms of HTTP functions.
The simplest payment flow with Payment Intents will be:
In Firebase, setup an HTTP endpoint, where you create a PaymentIntent and return a response, particularly the client_secret
In your app, you'll use a HTTP client to request the endpoint you created in Step 1. This will create a Payment Intent and return the client_secret to your application.
In your app, collect a user's card details.
Via your app, and using the client_secret and card details you collected above, confirm the Payment Intent

Related

Staying PCI Compliant with Stripe in a Flutter app

I'm integrating Stripe as the payment gateway an I'm looking at the flutter_stripe package it says on the tin
Simplified Security: We make it simple for you to collect sensitive data such as credit card numbers and remain PCI compliant. This means the sensitive data is sent directly to Stripe instead of passing through your server. For more information, see our Integration Security Guide.
So I was expecting an integration to call Stripe sdk directly as I do in my Nodejs server where I create the PaymentIntent as mentioned in Stripe custom flow guide
Create a PaymentIntent
Add an endpoint on your server that creates a PaymentIntent. A PaymentIntent tracks the customer’s payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the PaymentIntent’s client secret in the response to finish the payment on the client. (server)
Use Stripe.js to remain PCI compliant by ensuring that payment details are sent directly to Stripe without hitting your server. (client)
and confirm that PaymentIntent in my flutter app without hitting try server.
I was expecting to find in their API the equivalent of the Stripe node sdk
const paymentIntent = await stripe.paymentIntents.confirm(
'pi_1EUq4543klKuxW9fVKimzjFV',
{payment_method: 'pm_card_visa'}
);
but I found only the method
Future<PaymentIntent> confirmPayment( String paymentIntentClientSecret,PaymentMethodParams data,[ Map<String, String> options = const {},])
which does
Confirms a payment method, using the provided paymentIntentClientSecret and data.
See PaymentMethodParams for more details. The method returns a PaymentIntent. Throws a StripeException when confirming the paymentmethod fails
I see from their example app that they hit a server to register customers making the PCI Compliance go down the drain right?.
https://github.com/flutter-stripe/flutter_stripe/blob/main/example/server/src/index.ts
I'm sure I'm not understanding the package but their API confirmPayment just ads the paymentMethod to the PaymentIntent.
Any explanation will be very helpful.
Cheers
The sensitive information governed by PCI (i.e. raw card data) is sent directly from the client to Stripe. Stripe creates a Payment Method to represent that data (pm_) and returns that to the client so it can be referenced from there.
However, Payment Intents must be created server-side in a secure context with a secret or restricted API key, then the Payment Intent's client secret should be sent to the client to allow for client-side confirmation.
The section about validating your PCI compliance in Stripe's integration security guide has more information.

Replacing PayPal SetExpressCheckout SOAP API with REST API V2

We are in the process of replacing our Paypal SOAP API calls (SetExpressCheckout etc.) with the Paypal REST API V2.
Three questions:
1) Paypal has two similar APIs: orders and payments. Which one is considered to be the replacement for SetExpressCheckout?
2) We use the tokens returned by SetExpressCheckout to do a capture or refund later. Can the tokens we got from SetExpressCheckout also be used to do a capture / refund using the REST APIs? (If not, we cannot do a "big-bang" migration, but keep both implementations in place until we are sure no capture or refund will take place for transactions which have been issued with the SOAP API).
3) Does the merchant need to amend anything in his profile, e.g. give new rights to use the REST API? For example, we use SOAP API call TransactionSearch, which requires special rights - are those also valid for REST API calls?
1) Creating a v2/order replaces SetExpressCheckout. Capturing a v2/order replaces DoExpressCheckoutPayment. The capture will return a new transaction id that is a v2/payment object, and this v2/payment object id is the only thing that is preserved in www.paypal.com for accounting purposes (the v2/order id is not used for accounting; like an EC token, it is for the payment approval process only)
For the front-end, use
https://developer.paypal.com/demo/checkout/#/pattern/server
[ You mentioned capturing later, so the following won't apply to that particular case, but: if your flow were set up to capture right after approval with the buyer present, then -- once everything about your implementation is working for the happy path -- don't neglect to add support for handling funding source failures, so that if the immediate capture fails due to e.g. the buyer's first card being declined, this is propagated back to the UI and the buyer can select a different funding source right away ]
2) SetEC tokens cannot be mixed with REST APIs for capture
3) Yes and no. If you're using a REST API to search transactions, then what will matter are the permissions of the REST ClientID+Secret you are using. What will be most straightforward will be for the merchant to generate a new REST app in https://www.paypal.com/signin?intent=developer&returnUri=https%3A%2F%2Fdeveloper.paypal.com%2Fdeveloper%2Fapplications with all the necessary permissions, and provide you with that REST App's live ClientID+Secret.

RESTful Device specific Authentication of Phone Number

We have an API that sends a verification code to user's mobile number. The API is:
POST /api/users/verification/start/
{
"mobile": "9849735434"
}
The above API returns following response:
{
"isVerified": false
}
If the response is "isVerified": true, we don't send a verification code to user's mobile. If it is false, we send a code.
Currently, all this works on the just mobile number. We want to make it based on (mobile + device) to make it more secure.
To achieve this, we store a user-identification cookie on the client machine and we are planning to identify the device on basis of that. How should API be modified for this new requirement? Few approaches:
Create different API that works on basis of (mobile + cookie) and sends isVerified: true only if both matches with the value stored in our database.
Modify existing API to achieve this - Since this support for device-specific OTP is not required always, we will have to pass some flag to make it only mobile-based OR (mobile and cookie).
How should we design such API to verify users based on mobile and device?
Hope this would help you, you can modify code and follow some client and server steps.
CLIENT SIDE
Step 1.
Get mobile no and country from user
GET UUID from user device. ( UUID :Is Secure.ANDROID_ID unique for each device?)
Hit Own Api with this params.
SERVER SIDE
Step 2.
Get Validate it, is this mobile no is Valid https://github.com/googlei18n/libphonenumber (we can do it from Client side too)
Step 3.
Generate OTP between 0001 - 9999 or more
Send OTP api call to send on Mobile no as per OTP service provider’s API.
Save OTP no into database along with Mobile no And UUID.
CLIENT SIDE
Step 4.
get mobile no and OTP and hit api
check OTP from DB same OTP then response success else Wrong OTP message you can send.
There are different options.
When you want to use cookies, why do you need a separate API at all? If the client has a cookie, let the client send this cookie as a cookie. Your service can analyze the cookie when needed and decide about further steps.
If you cannot send cookies and the 1st approach is not an option to you:
Device should not know, what type is it from the point of view of your service. That is why I'd suggest to use two services - one without cookies and one with cookies.
You say "RESTful". In the current form your service is not RESTful.
A) Using verbs makes the service NOT RESTful. Rename it for instance to
"POST /api/users/verification/"
B) Two operations are mixed within a single one: Check if client is authenticated and starting authentication process. Split it into two:
To check if the client is authenticated:
"GET /api/users/verification/mobile/9849735434"
To start authentication:
"POST /api/users/verification/mobile/9849735434"
For the POST you don't need a body in this case.
I would modify the existing API to fit the new requirement and here is the important thing I would do while modifying.
Whenever you create any API always have a "version" passed from the client this way you would know which section of the code to execute.
e.g Assume your mobile users have 2 different version of the app, once before this release another after. To have both the user running versioning is helpful.
Pass "Device Type" from client to check whether the client is mobile/tab or other, this will have multiple advantages firstly you will know how much user base is in phone/web, another advantage is you can customize the output size accordingly as web will have more information compared to the mobile app.
Now that you have device and version information you just have to write condition in your existing API. Once you feel there is no old version usage we can retire that portion of API.

Create Twilio Conference With Rest API

I'm looking to create a Twilio Conference through the rest API. And I'm not sure how to start the conference. I'd prefer to do this without the SDK.
Heres the flow that I'm looking for.
In browser I enter a phone number to be called and click a call button.
A request is sent to my server. I handle my back end logic.
In PHP the rest API is used to hit Twilio and start a conference. (Hopefully connect the initial user via JS Client in this request)
Once the connection is established use the callback request to add a phone number to the conference.
I have used rest for outbound calls but I can't figure out how to set up a conference.
For outbound calls I use the rest endpoint https://api.twilio.com/version/Accounts/account/Calls.JSON
What would the endpoint be for creating a conference and adding the client?
I found https://api.twilio.com/version/Accounts/account/confrences.JSON
but it seems to be geared toward get requests for pulling data about conferences not creating an outbound conference.
Twilio developer evangelist here.
If you're saying that you'd like to make Twilio calls from the browser without the Twilio Client JS SDK, then I can't help you there. We don't publish the API and it's not recommended you try to write your own library.
You can achieve the flow you want here. You can use the REST API to generate a call to your client:
use Twilio\Rest\Client;
// Your Account Sid and Auth Token from twilio.com/user/account
$sid = "your_account_sid";
$token = "your_auth_token";
$client = new Client($sid, $token);
$call = $client->calls->create(
"client:CLIENT_IDENTITY", "YOUR TWILIO NUMBER",
array("url" => "YOUR APPLICATION URL")
);
Note, you need to use client:CLIENT_IDENTITY as the to number.
The URL you pass to this call should point to an endpoint on your server that will return the TwiML to start the conference:
<Response>
<Dial><Conference>Conference room name</Conference></Dial>
<Response>
During this request that you return the conference TwiML, you can also kick off a new request to start a call to the phone number you want to dial, again using the REST API.
Does this all make sense?

REST API: Providing redirect URIs to external services using client app domain

Background
I have a RESTful API accessed through the domain http://restapi.com
I have a client app using http://restapi.com. The client app has the domain http://myapp.com
The way I have my HATEOAS setup is that the API presents URIs without a domain. So instead of http://restapi.com/some/resource, it contains links to resources like so /some/resource. Example API json resource below:
{"_links":{"self":{"href":"/some/resource"}}}
The benefit this has is that the API doesn't need to know about the client app, and the client app has to do very little to get the correct resource from the API and doesn't have to reformat all the URIs in the resource. For example, in the client app, the following URI would be used by the browser http://myapp.com/some/resource. When the app gets the request, it then needs to call the API to get the resource and simply swaps the domain i.e. http://restapi.com/some/resource.
This has been successful so for, and allows a lot of flexibility to have different clients use the API with the only knowledge required being the initial end point (domain) of the API. It also completely decouples the API from the client apps.
The problem I have run into is that I have started using some external services (specifically PayPal adaptive payments) where I need to provide a redirect URL for cancelled payments and successful payments. For example, the browser navigates to http://myapp.com/payment. The resource returned by http://restapi.com/payment presents a link to PayPal. Without going into too much detail, the API has to ask PayPal for a payment ID, which can then be used to create a link to a PayPal payment e.g. http://paypal.com?PayId-123456. Part of the creation process requires that URLs are provided to redirect on payment cancellation or success. Again, don't want to go into details, but when requesting a PayId from PayPal, the redirect URLs are sent as variables to PayPal, and I guess PayPal stores them against the specific PayId created.
The browser navigates to the link returned in the resource - http://paypal.com?PayId-12345. Payment is made and PayPal then uses the redirect URLs as needed to redirect back to my app e.g. on successful completion of payment, PayPal should redirect to http://myapp.com/paymentcomplete. Note: I realise that this is not a restfully named URI, but it simplifies building up the description of my problem
Problem
The problem I have may now be obvious. I need to redirect back to http://myapp.com/paymentcomplete, BUT its the API that provides the redirect URL to PayPal. It has no knowledge of the client application. Since PayPal is an external service, the full URL must be provided. The best the API can do is send http://restapi.com/paymentcomplete as the redirect URL, but if PayPal redirects to this, the resulting response will be a JSON string (the output format of my API) not the nicely formatted page of the client app.
My question is, what is a good way to correctly provide the redirect URL to PayPal?
One thought I had was to make the client application handle creating the PayPal PayId, but I don't like this option as I would like to keep the creation of the PayPal payment ID on the API side. It would also require every client app to provide its own implementation, something I also don't want.
The other option I though of was to ask the client to provide its domain in the request. Currently the request the client makes to get the resource with the link to PayPal is GET http://restapi.com/payment, but I could use POST http://restapi.com/payment with the client providing its domain as a param. The API can then use this to construct the correct redirect URL. I don't really like this idea either as its seems a bit hackish and also requires the app to know that is must fill in this field i.e. a human user wouldn't fill the domain input in.
Additional solutions, or thoughts greatly welcomed.
As you had already mentioned, PayPal is an external api that requires this additional parameter and you do not have control over it. Looks like the client is the only party that can provide the Redirect URI Information.
Couple of ideas come to mind.
The client could send the redirect uri to restapi via header and thus
keeping your rest urls intact. This is a grey area and not a violation of restful api
in my opinion. (Then again, its just my opinion).
The restapi could return the response with a placeholder for the
client to fill in before rendering. This way the API need not know
about the redirect uri and the responsibility is left to the client
which has this information.
It would be nicer if you could implement option 2 with executing couple of lines on Javascript code on the browser to fill-in the placeholder. Which is easy. Ultimately, only 2 end points of this transaction would be aware of the redirect uri - browser & paypal.
This alleviates most of your concerns. The job of handling PayPal id will continue to remain with your API.
You should be able to use the Referer header to determine the client's full URI. It might be populated automatically for you. If not, you can add it yourself. The URI class has methods to pull out the client's host for you. When the API builds the PayPal URI to return to the client, it can include the client's host.
Note that referer is not always included and sometimes gets stripped by intermediaries, as detailed on the wiki page. Since you control both the client and the server in this case, you should be able to tell everybody to play nicely.
I would keep the GET http://restapi.com/payment and pass in a query param with the client domain
GET http://restapi.com/payment?domain=http://myapp.com (of course, the "http://myapp.com" needs to be encoded)