What are valid payment-method-tokens? - paypal

I'm trying to create a credit card and therefore I need to call paymentMethodNone(). According to the documentation I can
Use PaymentMethod.create() to create a payment method for an existing customer:
// It's not clear what A_PAYMENT_METHOD_TOKEN has to be
Result<PaymentMethodNonce> result = bt.paymentMethodNonce()
.create("A_PAYMENT_METHOD_TOKEN");
String nonceFromTheClient = result.getTarget().getNonce();
Customer customer = customerResult.getTarget();
PaymentMethodRequest paymentMethodRequest = new PaymentMethodRequest()
.customerId(customer.getId())
.paymentMethodNonce(nonceFromTheClient);
Result<? extends PaymentMethod> paymentMethodResult = bt.paymentMethod()
.create(paymentMethodRequest);
PaymentMethod paymentMethod = paymentMethodResult.getTarget();
However, no word about what valid tokens are in the documentation. Neither here nor here - or am I just blind?

Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
You do not need a payment_method_token to create a PaymentMethod.
To create a credit card, you will need to create a PaymentMethod. First, retrieve the payment_method_nonce from the incoming request. Next, create the PaymentMethod using PaymentMethodRequest.
//payment_method_nonce will be a post parameter in the request
//set nonceFromTheClient to equal payment_method_nonce
PaymentMethodRequest paymentMethodRequest = new PaymentMethodRequest()
.customerId(customer.getId())
.paymentMethodNonce(nonceFromTheClient);
Result<? extends PaymentMethod> result = gateway.paymentMethod().create(request);

Related

Do country have any significance in credit card transaction

I went into the developer portal and created a test account for a non US account. Transaction with this credit card number with the C# code below works fine.
But, my question is whatever the country code is provided, paypal soap api allow me to do the transaction without out any problem. Is this a correct behavior or there is some setting that can enforce the API to validate the country.
//address of the card owner
var cardOwnerAddress = new AddressType
{
Street1 = request.BuyerAddress1,
Street2 = request.BuyerAddress2,
CityName = request.BuyerCity,
StateOrProvince = request.BuyerState,
PostalCode = request.BuyerZipCode,
CountryName = "USA",
Country = CountryCodeType.US, // country code
CountrySpecified = true
};
//card owner object
var cardOwner = new PayerInfoType
{
Payer = "",
PayerID = "",
PayerStatus = PayPalUserStatusCodeType.unverified,
PayerCountry = cardOwnerAddress.Country, // country code
Address = cardOwnerAddress,
PayerName = cardOwnerPayerName
};
Typically, with AVS - Address Verification System(s), and also CVV2 the most done is checking the street number and numbers from the postal/zip code (numbers because they are constant, where people can type "st.", "street", "st" etc for their address. Thus the country really doesn't matter.
Names, for some cards, can be checked too, though as you can imagine, this can be a pain with people not typing their name exactly as it appears.
You can also, with PayPal, set filters in your account to specify which countries you will accept payment for - though this has nothing to do with verification, it's just PayPals layer on top.
Paypal list out what verification you can set up here
https://developer.paypal.com/docs/classic/api/AVSResponseCodes/
And a little information on AVS can be found here https://en.wikipedia.org/wiki/Address_Verification_System

Mark an order as "Full Payment" on Sage 200

I am inserting orders on Sage 200 through an application using the client side, C# and APIs.
I would like to check the "Full payment" checkbox on the "Payment with order" tab.
Currently, I am setting the PaymentType property, which is not working.
order.PaymentType = Sage.Accounting.SOP.SOPOrderPaymentTypeEnum.EnumSOPOrderPaymentTypeFull;
order is an instance of Sage.Accounting.SOP.SOPOrder.
Do you know how I can check that property?
The following method should supply the required results.
private static void SetPaymentWithOrder(Sage.Accounting.SOP.SOPOrder sopOrder)
{
// Indicate that order has payment
sopOrder.PaymentWithOrder = true;
// This is full payment order
sopOrder.PaymentType = Sage.Accounting.SOP.SOPOrderPaymentTypeEnum.EnumSOPOrderPaymentTypeFull;
// Fetch the the Payment Methods. SOPPaymentMethods contructor accepts the boolean flag whether to fetch payment methods including card processing method or not.
Sage.Accounting.SOP.SOPPaymentMethods paymentMethodsCollection = new Sage.Accounting.SOP.SOPPaymentMethods(false);
// Set the first payment method of the collection to the order
sopOrder.PaymentMethod = paymentMethodsCollection.First;
}
dont know if you ever managed to figure this one out or not.
Not sure if you knew this, but you cannot modify the Sales Order on the view form, or at least shouldn't be trying to do so.
Using either of the Enter/Amend Sales Order forms will allow you to do so.
What is potentially happening, is that the properties that the controls are bound to are not updating the UI after your code has run.
You can simply force this to happen using the following
Fetching the underlying bound object
public Sage.Accounting.SOP.SOPOrderReturn SOPOrderReturn
{
get
{
//Loop over the boundobjects collection
//check if the bound object is of the type we want - e.g. SOPOrderReturn
//if correct type, return this object
Sage.Common.Collections.BoundObjectCollection boundObjects = this.form.BoundObjects;
if (boundObjects != null)
{
foreach (object boundObject in boundObjects)
{
if (boundObject is Sage.Accounting.SOP.SOPOrderReturn)
{
this._sopOrderReturn = boundObject as Sage.Accounting.SOP.SOPOrderReturn;
break;
}
}
}
return this._sopOrderReturn;
}
}
Fetch the correct underlying form type that the amendable form is, suspending the databinding,
perform your changes,
resuming the databinding
Sage.MMS.SOP.MaintainOrderForm maintainOrderForm = this.form.UnderlyingControl as Sage.MMS.SOP.MaintainOrderForm;
maintainOrderForm.BindingContext[this.SOPOrderReturn].SuspendBinding();
this.SOPOrderReturn.PaymentWithOrder = true;
this.SOPOrderReturn.PaymentType = Sage.Accounting.SOP.SOPOrderPaymentTypeEnum.EnumSOPOrderPaymentTypeFull;
maintainOrderForm.BindingContext[this.SOPOrderReturn].ResumeBinding();
should do the trick.

PayPal Merchant SDK GetExpressCheckoutDetailsResponseDetails not returning buyer's email or phone number

I'm using the PayPal Merchant SDK for .NET (v 2.15.117) and am trying to retrieve the shipping address info, customer's email address, and phone number from the GetExpressCheckoutDetailsRequestType.GetExpressCheckoutDetailsResponseDetails call. The shipping address is populated as expected but for the life of me, I can't figure out how to get the buyer's email or phone number. At a minimum we have to have the email to communicate about the order (ie tracking emails).
I see a BuyerMarketingEmail property but it is null and I am under the impression that is an optional email the buyer can choose to provide. For phone, I see a PayerInfo.ContactPhone property but that is also null (and I'm less concerned about having that but it would be nice for customer service issues or to give to ground shippers like FedEx).
I am using the PayPal sandbox if that matters.
What am I missing?
var getExpressCheckoutDetails = new GetExpressCheckoutDetailsReq();
var getExpressCheckoutDetailsRequest = new GetExpressCheckoutDetailsRequestType(token);
getExpressCheckoutDetails.GetExpressCheckoutDetailsRequest = getExpressCheckoutDetailsRequest;
var service = new PayPalAPIInterfaceServiceService();
paypalResponse = service.GetExpressCheckoutDetails(getExpressCheckoutDetails);
if (paypalResponse != null)
{
//Success values check for a matching PayerID to validate the token response
if (paypalResponse.Ack.ToString().Trim().ToUpper().Equals("SUCCESS") &&
PayerID == paypalResponse.GetExpressCheckoutDetailsResponseDetails.PayerInfo.PayerID)
{
checkout.ShippingInfo.ShippingName = paypalResponse.GetExpressCheckoutDetailsResponseDetails.PayerInfo.Address.Name;
checkout.ShippingInfo.ShippingAddress1 = paypalResponse.GetExpressCheckoutDetailsResponseDetails.PayerInfo.Address.Street1;
checkout.ShippingInfo.ShippingAddress2 = paypalResponse.GetExpressCheckoutDetailsResponseDetails.PayerInfo.Address.Street2;
checkout.ShippingInfo.ShippingCity = paypalResponse.GetExpressCheckoutDetailsResponseDetails.PayerInfo.Address.CityName;
checkout.ShippingInfo.ShippingState = paypalResponse.GetExpressCheckoutDetailsResponseDetails.PayerInfo.Address.StateOrProvince;
checkout.ShippingInfo.ShippingZip = paypalResponse.GetExpressCheckoutDetailsResponseDetails.PayerInfo.Address.PostalCode;
checkout.ShippingInfo.ShippingCountry = paypalResponse.GetExpressCheckoutDetailsResponseDetails.PayerInfo.Address.Country.ToString();
//these next two are always null
checkout.BillingInfo.Email = paypalResponse.GetExpressCheckoutDetailsResponseDetails.BuyerMarketingEmail;
checkout.ShippingInfo.PhoneNumber = paypalResponse.GetExpressCheckoutDetailsResponseDetails.PayerInfo.ContactPhone;
}
}
Thought I'd post an answer to wrap this up -
As stated above in my comment to the original question, the email address of the buyer is PayerInfo.Payer.
Also, suddenly/magically, PayerInfo.ContactPhone began returning the phone number instead of null. I can only chalk that up to something in the Sandbox environment or my sandbox user account.

Is it possible to allow partial payments using the PayPal Invoicing SDK?

Is it possible to allow partial payments using the PayPal Invoicing SDK?
I have tried setting the allowPartialPayments attribute to true on the InvoiceType object(see below) although once the invoice has been received there is no option to change the amount being paid.
InvoiceItemListType itemList = new InvoiceItemListType(invoiceItemList);
InvoiceType invoice = new InvoiceType(_MerchantEmailAddress, payerEmailAddress, itemList, "GBP");
invoice.number = brightStartInvoiceId.ToString();
invoice.merchantMemo = brightStartChildId.ToString();
invoice.allowPartialPayments = true;
CreateAndSendInvoiceRequest requestCreateAndSendInvoice = new CreateAndSendInvoiceRequest(envelopeRequest, invoice);

delayed chained payment

Can anyone tell me how to automatically execute a delayed payment (let's say it's 5 days after the primary receiver receive the payment) in a chained payment manner? The key is automatic execution, not having to manually approve and pay the secondary receiver. Please illuminate with some sample code.
I have used "actionType" => "PAY_PRIMARY" so that primary receiver get money.
But how can I code so that secondary receiver get money?
Check this answer for the solution. Basically you just need to execute an ExecutePayment operation with the payKey within 90 days to send the payment to the secondary party.
actionType is PAY_PPRIMARY
you then trigger this payment within 90 days.
Its delayed but not time-elapsed.
https://cms.paypal.com/cms_content/US/en_US/files/developer/PP_AdaptivePayments.pdf
well may be its too late but it will help someone in future for sure.
As we integrated paypal delayed chained payment, you can set a primary account in which all the amount will go and you can also set secondary account in which account will be transfered once they approved by primary account holder.
string endpoint = Constants_Common.endpoint + "Pay";
NVPHelper NVPRequest = new NVPHelper();
NVPRequest[SampleNVPConstant.requestEnvelopeerrorLanguage] = "en_US";
//NVPRequest[SampleNVPConstant.Pay2.actionType] = "PAY";
//the above one is for simple adoptive payment payment
NVPRequest[SampleNVPConstant.Pay2.actionType] = "PAY_PRIMARY";
//the above one for deleayed chained payment
NVPRequest[SampleNVPConstant.Pay2.currencyCode] = "USD";
NVPRequest[SampleNVPConstant.Pay2.feesPayer] = "EACHRECEIVER";
NVPRequest[SampleNVPConstant.Pay2.memo] = "XXXXXXXX";
Now we have to set primary and secondary receivers:
//primary account
NVPRequest[SampleNVPConstant.Pay2.receiverListreceiveramount_0] = TotalAmount;
NVPRequest[SampleNVPConstant.Pay2.receiverListreceiveremail_0] = "XXXx.xxxxx.com";
NVPRequest[SampleNVPConstant.Pay2.receiverListreceiverprimary_0] = "true";
//secondary accounts
NVPRequest[SampleNVPConstant.Pay2.receiverListreceiveramount_1] = (somemoney out of total amount);
NVPRequest[SampleNVPConstant.Pay2.receiverListreceiveremail_1] = "xxxxx.xxxx.com";
NVPRequest[SampleNVPConstant.Pay2.receiverListreceiverprimary_1] = "false";
NVPRequest[SampleNVPConstant.Pay2.receiverListreceiveramount_2] = (somemoney out of total amount);
NVPRequest[SampleNVPConstant.Pay2.receiverListreceiveremail_2] = x.x.com;
NVPRequest[SampleNVPConstant.Pay2.receiverListreceiverprimary_2] = "false";
Don't forget that you have to give a valid paypal account while using delayed chained payment.
Now you get your pay_key which you have to use to execute your payment whithin 90 days so that other secondary receivers get money.
Here is the working code:
String endpoint = Constants_Common.endpoint + "ExecutePayment";
NVPHelper NVPRequest = new NVPHelper();
//requestEnvelope.errorLanguage is common for all the request
NVPRequest[SampleNVPConstant.requestEnvelopeerrorLanguage] = "en_US";
NVPRequest[SampleNVPConstant.ExecutePayment.payKey] = "your pay key";
string strrequestforNvp = NVPRequest.Encode();
//calling Call method where actuall API call is made, NVP string, header value adne end point are passed as the input.
CallerServices_NVP CallerServices = new CallerServices_NVP();
string stresponsenvp = CallerServices.Call(strrequestforNvp, Constants_Common.headers(), endpoint);
//Response is send to Decoder method where it is decoded to readable hash table
NVPHelper decoder = new NVPHelper();
decoder.Decode(stresponsenvp);
if (decoder != null && decoder["responseEnvelope.ack"].Equals("Success") && decoder["paymentExecStatus"].Equals("COMPLETED"))
{
//do something
}
Hope it will help someone.