In CyberSource, how do you use a credit card flexible token with payments API? - cybersource

Trying to get my head around how CyberSource works..
In CyberSource, the Secure Acceptance Flexible Token API can be used to tokenize a credit card on client-side for processing for future processing.
That part is easy enough. There's plenty of documentation and a few packages that do it.
How do I then use that token to create a charge with the CyberSource Payments API ?
All examples i've found show how to tokenize the card on client, and how to charge an untokenized card (i.e. card data is sent to server) but I can't find an example that show how to use the Flexible token to create a charge (or pre-auth).
In most other gateways like Stripe, it's pretty clear in documentations but CyberSource doesn't seem to provide that.
Am I missing something?
I'm using Node but happy with solutions in other languages.
https://developer.cybersource.com/api-reference-assets/index.html#flex
https://developer.visa.com/capabilities/cybersource/reference

Ok, thanks to #rhldr for pointing out to this particular documentation.
The answer is in this page https://developer.cybersource.com/api/developer-guides/dita-flex/SAFlexibleToken/FlexMicroform/GetStarted.html under "Using the Token".
Note: Some of the other documentations (not sure why they have some many variations of the docs), like this one don't mention this at all.
See the RESTPaymentAPI section. It needs to be provided as a customerId field.
"paymentInformation": {
"customer": {
"customerId": "7500BB199B4270EFE05340588D0AFCAD"
}
}
Here's a minimal example of how it can be implemented on the API side
var cybersourceRestApi = require('cybersource-rest-client');
var configuration = require('./cybersource/config.js');
var configObject = new configuration();
var instance = new cybersourceRestApi.PaymentsApi(configObject);
var clientReferenceInformation = new cybersourceRestApi.Ptsv2paymentsClientReferenceInformation();
clientReferenceInformation.code = 'test_payment';
var processingInformation = new cybersourceRestApi.Ptsv2paymentsProcessingInformation();
processingInformation.commerceIndicator = 'internet';
var amountDetails = new cybersourceRestApi.Ptsv2paymentsOrderInformationAmountDetails();
amountDetails.totalAmount = "100.00";
amountDetails.currency = 'USD';
var orderInformation = new cybersourceRestApi.Ptsv2paymentsOrderInformation();
orderInformation.amountDetails = amountDetails;
var paymentInformation = new cybersourceRestApi.Ptsv2paymentsPaymentInformation();
// THIS IS THE IMPORTANT BIT
var customer = new cybersourceRestApi.Ptsv2paymentsPaymentInformationCustomer()
customer.customerId = token
paymentInformation.customer = customer
var request = new cybersourceRestApi.CreatePaymentRequest();
request.clientReferenceInformation = clientReferenceInformation;
request.processingInformation = processingInformation;
request.orderInformation = orderInformation;
request.paymentInformation = paymentInformation;
if (!authoriseOnly) {
request.processingInformation.capture = true;
}
Code based on the CyberSource nodejs REST samples: https://github.com/CyberSource/cybersource-rest-samples-node
More info. Once you know where to look, it's actually explained in a few places.
Example, go to https://developer.cybersource.com/cybs-dev-api-ref/index.html#payments-process-a-payment, expand the "REQUEST FIELD DESCRIPTION" underneath and go to
customer
.. customerId
Unique identifier for the customer's card
and billing information.
When you use Payment Tokenization or Recurring Billing and you include
this value in your request, many of the fields that are normally
required for an authorization or credit become optional.
NOTE When you use Payment Tokenization or Recurring Billing, the value
for the Customer ID is actually the Cybersource payment token for a
customer. This token stores information such as the consumer’s card
number so it can be applied towards bill payments, recurring payments,
or one-time payments. By using this token in a payment API request,
the merchant doesn't need to pass in data such as the card number or
expiration date in the request itself.
See "Payment Tokenization," page 222, and "Recurring Billing," page
225.

Related

How to get transfer data from stripe using payment id and account id (.Net)

I am trying to get transfer related data from stripe
TransferService service = new TransferService();
TransferListOptions stripeTransferList = new TransferListOptions
{
Destination = accountId,
Limit = 100
};
var list = await service.ListAsync(stripeTransferList);
var finalData = list.FirstOrDefault(x => x.DestinationPaymentId == paymentId);
so when I try to search paymentId from that list I was not able to find any because the page limit is 100 only
Limit = 100
how to fetch all the data and filter from that??
The stripe-dotnet library supports automatic pagination and it's documented here.
This lets you paginate through all the data in your account based on specific criteria that you passed as parameters. For example you can list all Transfer objects made to a specific connected account this way:
TransferService service = new TransferService();
TransferListOptions listOptions = new TransferListOptions
{
Destination = "acct_123456",
Limit = 100
};
foreach (var transfer in service.ListAutoPaging(listOptions)) {
// Do something with this Transfer
}
Now, this allows you to iterate over every Transfer but if you have a lot of data this could be quite slow. An alternative would be to start from the charge id, the py_123456 that you have from your connected account. If you know which account this charge was created on, you can fetch it directly via the API. This is done using the Retrieve Charge API along with passing the connected account id as documented here.
The Charge resource has the source_transfer property which is the id of the Transfer (tr_123) from the platform that created this charge. You can also use the Expand feature, which lets you fetch the entire Transfer object back to get some detailed information about it.
The code would look like this
var transferOptions = new TransferGetOptions{};
transferOptions.AddExpand("source_transfer");
var requestOptions = new RequestOptions();
requestOptions.StripeAccount = "acct_12345";
TransferService service = new TransferService();
Charge charge = service.Get(transferOptions, requestOptions);
// Access information about the charge or the associated transfer
var transferId = charge.SourceTransfer.Id;
var transferAmount = charge.SourceTransfer.TransferData.Amount;

Firebase Cloud Messaging: Unable to correlate SendResponse to subscriber token

I'm using the Java SDK for Firebase Cloud Messaging and want to send out a batch (or multicast) of messages. In case I send 100 messages I get 100 SendResponse's returned. But I don't see how I can relate those to the tokens/subscribers. There is a messageId in the successful ones but I can't use that to relate it to the tokens.
What am I missing? Or is this a limitation of the API/SDK?
You will have to manually manage a mapping of device tokens to users. Device tokens just identify a device, not a user. And a user could be using multiple devices, so it is actually a one to many mapping. But there's no avoiding keeping track of this mapping on your own.
According to the server environments docs on sending messages to multiple devices, the order of the list of SendResponses corresponds to the order of the input tokens:
The return value is a BatchResponse whose responses list corresponds to the order of the input tokens. This is useful when you want to check which tokens resulted in errors.
You can use this fact to determine the token -> SendResponse mapping, as shown by the example code on that page:
// These registration tokens come from the client FCM SDKs.
List<String> registrationTokens = Arrays.asList(
"YOUR_REGISTRATION_TOKEN_1",
// ...
"YOUR_REGISTRATION_TOKEN_n"
);
MulticastMessage message = MulticastMessage.builder()
.putData("score", "850")
.putData("time", "2:45")
.addAllTokens(registrationTokens)
.build();
BatchResponse response = FirebaseMessaging.getInstance().sendMulticast(message);
if (response.getFailureCount() > 0) {
List<SendResponse> responses = response.getResponses();
List<String> failedTokens = new ArrayList<>();
for (int i = 0; i < responses.size(); i++) {
if (!responses.get(i).isSuccessful()) {
// The order of responses corresponds to the order of the registration tokens.
failedTokens.add(registrationTokens.get(i));
}
}
System.out.println("List of tokens that caused failures: " + failedTokens);
}
As Doug mentioned in his answer, associating the input tokens to users is something you'll need to manage yourself. In a relational database you'd probably have a FCM_Token table that includes a foreign key to a User table.

GCalendar API - Exclude Events By ID?

I'm particularly trying to write this in C#, but has anyone managed to create a LIST request for events that OMIT events by a list of IDs? The idea here is to omit Google Calendar events that I've already pulled before in my previous requests (this would be stored in my application data) so that the events are always new. Here's my current list request code below:
// Create Google Calendar API service.
var service = new v3GCal.CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
var today = DateTime.Today;
var tomorrow = today.AddDays(1);
// Define parameters of request.
v3GCal.EventsResource.ListRequest request = service.Events.List("manager#affirmmedicalweightloss.com");
request.TimeMin = today;
request.TimeMax = tomorrow;
request.ShowDeleted = false;
request.SingleEvents = true;
request.Q = "";
request.MaxResults = 10;
request.OrderBy = v3GCal.EventsResource.ListRequest.OrderByEnum.StartTime;
I'm not too hopeful - I've been digging around trying to find something with this feature, but with no luck. I would ideally include in the request something like:
"id NOT IN " + collection of existing id strings
But I don't see documentation on this anywhere.
Has anyone pulled this off, or considered filing a feature request for it? I thought of filing one, but given the issue tracker that I found at issuetracker.google.com, I'm not too hopeful this would get implemented anytime soon...
If your issue is regarding recurring event, you can try to use Events: instances that returns instances of the specified recurring event. Doing so excludes the recurring events, but includes all expanded instances. If not, you can file a bug here.

How to get Google UserId from active user session in App Maker?

Is there a way to get "User Google Id" from the session in App Maker. In the documentation its only mentioned how to retrieve the email of the logged in user Session.getActiveUser().getEmail() but no where it says how to get the id. I need this because the user email might sometimes changes. So I need the user id to keep track of users and related permission tasks. Or is there something I'm missing out here in how this should be implemented.
Yet an easier way to find Google Id simply using the Directory model. Although its mentioned in documentation that there is a way to get current signed in user id ( which is Google Id), its not clearly stated how - maybe documentation could be improved here. Another problem is that in many occasions the email of current active user is referred to as the id for example in deprecated method Session.getActiveUser().getUserLoginId(). Anyways this is a proper way to get the id.
var query = app.models.Directory.newQuery();
query.filters.PrimaryEmail._equals = Session.getActiveUser().getEmail();
var result = query.run();
var GoogleId = result[0]._key;
So with this GoogleId you can safely relate different models with each other and not worry that database integrity might break if an already referenced user email is changed.
Relating the different models could be done simply by creating a model that acts as a wrapper model around the Directory model and storing GoogleId in it. Then linking that model to other models where you want to track user related data because unfortunately we can not directly link The Directory Model to other models.
A team member has figured it out. This should be done using Apps Script - which works within App Maker environment using server side script.
var GoogleUser = (function (){
/**
*
* #param {string} email
*/
function getUserObjByEmail(email){
// Same as using AdminDirectory class.
var apiUrl = "https://www.googleapis.com/admin/directory/v1/users/"+email+"?fields=id";
var token = ScriptApp.getOAuthToken();
var header = {"Authorization":"Bearer " + token};
var options = {
"method": "GET",
"headers": header
};
var response = JSON.parse(UrlFetchApp.fetch(apiUrl, options));
return response;
}
/**
*
* #param {string} email - User email.
*/
function getIdByEmail(email){
return getUserObjByEmail(email)['id'];
}
var publicApi = {
getIdByEmail: getIdByEmail
};
return publicApi;
})();
Note that using var apiUrl = "https://www.googleapis.com/admin/directory/v1/users/"+email+"?fields=id"; is not going to be asynchronously called because its already happening in the server.
Is this a dup of this question?
I think this will solve your problem, even though it's a bit of a hack.

Create an agreement for two signers via Rest API

How can we create an agreement using a library document using a library document which will be singed by two signers? I know how to do the same using echo sign web application using this tutorial: https://helpx.adobe.com/sign/help/send-agreement---multiple-signers.html
I have created a template document in my dashboard for reuse purpose and I have added fields for recipients as well. But when I create agreement using that library document and from that agreement I create signing url. But both URLs only allow one of them to sign. If the second signer opens their link, the document shows as already signed. Can anyone tell me how can I create and have my both signers complete the agreement using Rest API?
please change your lines of code from
//Create recipient set info
var recipientSetInfo = new agreementsModel.RecipientSetInfo();
recipientSetInfo.setRecipientSetMemberInfos(recipientSetMemberInfos);
recipientSetInfo.setRecipientSetRole(agreementsModel.RecipientSetInfo.RecipientSetRoleEnum.SIGNER);
recipientSetInfo.setRecipientSetName("fjenning#adobe.com");
var recipientSetInfos = [];
recipientSetInfos.push(recipientSetInfo);
to this
var recipientSetInfos = [];
//Create recipient set info
for (var i = 0; i < recipientSetMemberInfos.length; i++) {
var recipientSetInfo = new agreementsModel.RecipientSetInfo();
recipientSetInfo.setRecipientSetMemberInfos(recipientSetMemberInfos[i]);
recipientSetInfo.setRecipientSetRole(agreementsModel.RecipientSetInfo.RecipientSetRoleEnum.SIGNER);
recipientSetInfo.setSigningOrder("SEQUENTIAL");
recipientSetInfo.setRecipientSetName(" Recepients");
recipientSetInfos.push(recipientSetInfo);
}

Resources