Associate Braintree PaymentMethod with an Address - ruby

require 'braintree'
# set credentials
Braintree::Configuration.merchant_id = 'XXX'
Braintree::Configuration.public_key = 'YYY'
Braintree::Configuration.private_key = 'ZZZ'
Braintree::Configuration.environment = :sandbox
# see the raw messages going to and from the Braintree server
Braintree::Configuration.logger = Logger.new(STDERR)
Braintree::Configuration.logger.level = Logger::DEBUG
customer = Braintree::Customer.create!(first_name: 'John', last_name: 'Doe')
begin
address = Braintree::Address.create!(customer_id: customer.id, locality: 'London')
pmethod = Braintree::PaymentMethod.create(customer_id: customer.id, billing_address_id: address.id, payment_method_nonce: 'fake-valid-visa-nonce')
p pmethod
ensure
# always delete the Customer in order not to leave much rubbish
# behind the testing session
Braintree::Customer.delete(customer.id)
end
I create a Customer, than an Address for him. When I attempt to create a PaymentMethod, using a nonce representing a credit card, and provide a billing address (by means of an ID of the previously saved Address), the PaymentMethod is not saved and error result is returned. The p pmethod line prints
#<Braintree::ErrorResult params:{...} errors:<credit_card:[(91701) Cannot provide both a billing address and a billing address ID.]>>
The error message doesn't make sense, as I only provide billing address ID. I have also checked that the SDK doesn't e.g. forge an empty address and send it to the server together with the PaymentMethod data provided in my code.
Creating a PaymentMethod without billing address works, but I really want to specify one.

Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
Bottom-line: At this time, you cannot test the billing_address_id with a test nonce, but it will work with a nonce generated for the sandbox from a Drop-in or Custom Integration at the client side.
This is a limitation of the testing API itself. When you submit one of the test nonces, it pre-populates with data that is commonly required for various checks. One of those pre-populated fields is that of billing_address=>zip_code which you can see if you do a vanilla payment method create with the fake nonce you are using. billing_address can be overwritten with whatever test values you want, but you can't undo it or zero it out.

Related

Discord.py | How do I get a User Tag from an ID?

I am programming an entertainment bot with discord.py, and I want to code a function that allows you to look at other users' in game money and stuff with replit databases. Since making data with a user tag is inefficient since people change their usernames and tags all the time, I am using IDs. I am trying to find a way to get a user tag (eg. Dude#1234) from a user number id (eg. 871954599731396648). I couldn't find a solution. I already know how to use ctx.message.author.id but I can't find a way to make that work with every discord user.
To get the tag you can use the following method
user = await bot.fetch_user(ID) # ID must be an int and this could be could be client for you, be careful as this pings the API and can be abused if not correctly limited.
# user.discriminator will return their tag.
You can check all attributes that user can have here
To get the tag, you first have to get the user object from the id using discord.utils.get:
user_id = #insert the id of the user which you want the tag of
user = await discord.utils.get(client.get_all_members(), id =user_id)#might by something like bot.get_all_members for you
tag = user.name

How to work with not (yet) registered devise Users

I have a User model, for login and registration, its email field is used (everything vanilla from the devise gem).
I want (other) users to be able to e.g. add Users to a team, with the email-address as the identifier.
That is fine when the User is already existing (pseudo #team.users.add(User.find_by(email: other_users_email))) but I am unsure how to handle situations where the user does not yet exist (did not [yet] register).
When a (new) User sets up a new account, for the example above after successfull registration current_user.teams should show up correctly.
I do not want to force these potentially new users to use the system (e.g. using devise_invitable) and bother them with an email.
I followed the path of creating the User when a user with the given email does not yet exist, but then when the user actually tries to setup an account, it fails (email not unique).
Alternatively, I could remodel the TeamMember-part and let it optionally either store an email-adress or the reference to an existing User. Then what I would need is to check for "open" TeamMembers directly after User-Account-creation (so, TeamMembers with the given email). I could also do this on each requst, but that looks too expensive to me. There might be race conditions, but I could live with that (and check for the every-now-in-a-millenia-gap with a cron-job).
Any pointers? I am sure this is not that unusual.
I'd do this:
When a user A adds user B to a team by email, create the object for that user B, but set a flag, something like auto_created_and_inactive: true
When user B signs up on the site, you just have to handle this in your users#create: first, try to find an auto-created record and update it (set a password or whatever; also reset the flag). Or otherwise proceed with the usual route of creating a new record.
I have to admit that I did not yet tried #sergio-tulentsevs approach (implement RegistrationController#create). But to complete what I sketched in my question:
User model can define an after_confirmation method, which is called after ... confirmation! So, if I store every information about a potential user with a reference to his/her email-adress, once he/she registered I can query this information and e.g. complete Team-Memberships.
# app/models/user.rb
def after_confirmation
# (pseudo-code, did not try)
self.teams < TeamMembership.open.where(email: self.email)
end

Attach shipping information to Stripe Charge using Go

I'm trying to create a new charge via the Go API. I have a shipping address and a payment token. But the Go API doesn't seem to support sending the shipping address. The documentation indicates that it should support it but there isn't a direct mapping between the arguments described in the docs and the Go ChargeParams arguments and some are missing.
type ChargeParams struct {
Params
Amount uint64
Currency Currency
Customer, Token string
Desc, Statement, Email string
NoCapture bool
Fee uint64
Fraud FraudReport
Source *SourceParams
}
Is there some other way that I'm supposed to add the address that I'm missing?
I know nothing about Stripe's API but if you follow the fields of the struct, you find Charge ➜ Source ➜ Card ➜ Address1, Address2, City, State, Zip, Country. Is that what you are after?
Answer from Stripe support.
Thanks for writing in about this, I'm happy to help! Unfortunately our
go bindings don't support that parameter at the moment which is why
you couldn't find it in the source. The temporary solution would be to
create the POST request yourself when you need to send the shipping
details along with the charge.
I've forwarded this internally to make sure it gets addressed in the
future but unfortunately I don't have any timeline to share with you
at the moment. We are definitely open to a Pull Request from one of
our users so if that's something you'd feel comfortable building
yourself that would be awesome!
Here's how to use ChargeParams to include shipping infomation https://github.com/stripe/stripe-go/blob/master/charge/client_test.go
charge, err := New(&stripe.ChargeParams{
Amount: stripe.Int64(11700),
Currency: stripe.String(string(stripe.CurrencyUSD)),
Source: &stripe.SourceParams{Token: stripe.String("src_123")},
Shipping: &stripe.ShippingDetailsParams{
Address: &stripe.AddressParams{
Line1: stripe.String("line1"),
City: stripe.String("city"),
},
Carrier: stripe.String("carrier"),
Name: stripe.String("name"),
}
})

UPS Address validation using only Zipcode

I am using UPS API for address validation. I am very new to this API and have just started learning.
I want to validate an address based on only zipcode i.e. I don't want to suppy the State name. It is not working in Test Integration environment. Any help?
I want to validate address using only Street Address and Zipcode. I don't want to supply State & City name. Is that possible? So far not working.
If I provide both State & Zipcode it is working nice.
How committed are you to the UPS API? My experience is that if they don't have it in the API already, it won't happen soon. There are other APIs available that will let you verify an address based on only the address and the ZIP code. typically, it is not necessary to provide a city or state if you have the correct ZIP code. The minimum required for address validation is street address and zip code or street address and city/state. how many addresses to need to verify each month? If you don't need a whole lot, there are a number of free APIs available. National address server is one, SmartyStreets.com is another. (I work for SmartyStreets.com.)
If you provide blank values for PoliticalDivision1 and PoliticalDivision2 the result back should include the city and state. You must still provide a valid address.
In a C++ application the following XML input used in street level address validator UPS API. Please use appropriate licence number, user id and password.
<?xml version=\"1.0\"?>
<AccessRequest xml:lang=\"en-US\"><AccessLicenseNumber>{LicenceNo}</AccessLicenseNumber><UserId>{UserId}</UserId><Password>{Passwd}</Password></AccessRequest>
<?xml version=\"1.0\"?>
<AddressValidationRequest xml:lang=\"en-US\">
<Request><TransactionReference><CustomerContext>Your Test Case Summary Description</CustomerContext><XpciVersion>1.0</XpciVersion></TransactionReference><RequestAction>XAV</RequestAction><RequestOption>3</RequestOption>
</Request>
<AddressKeyFormat><AddressLine>608 E. Evergreen Rd</AddressLine><PoliticalDivision2>LEBANON</PoliticalDivision2> <PoliticalDivision1>PA</PoliticalDivision1><PostcodePrimaryLow>17042</PostcodePrimaryLow><CountryCode>US</CountryCode> </AddressKeyFormat>
</AddressValidationRequest>
and following output received.
<?xml version=\"1.0\"?>
<AddressValidationResponse>
<Response>
<TransactionReference><CustomerContext>Your Test Case Summary Description</CustomerContext> <XpciVersion>1.0</XpciVersion></TransactionReference> <ResponseStatusCode>1</ResponseStatusCode><ResponseStatusDescription>Success</ResponseStatusDescription>
</Response>
<ValidAddressIndicator/>
<AddressClassification><Code>1</Code><Description>Commercial</Description></AddressClassification>
<AddressKeyFormat><AddressClassification><Code>1</Code><Description>Commercial</Description></AddressClassification><AddressLine>608 E EVERGREEN RD</AddressLine><Region>LEBANON PA 17042-7925</Region><PoliticalDivision2>LEBANON</PoliticalDivision2><PoliticalDivision1>PA</PoliticalDivision1><PostcodePrimaryLow>17042</PostcodePrimaryLow><PostcodeExtendedLow>7925</PostcodeExtendedLow><CountryCode>US</CountryCode></AddressKeyFormat>
</AddressValidationResponse>
Another potential solution besides the UPS API is the Service Objects address validation web service. Full disclosure, I work for Service Objects, but the web service objectively fits your needs.
It can process addresses with just the address1 and zipcode fields. The web service can validate the information, append the city, state, zip+4, note any corrections/changes, and provide a Delivery Point Validation (DPV) code indicating the address's deliverability. Below is an example input and output showing the actual service response.
If you are interested in trying out the API a free trial key is available for testing. You want to get more information about the nitty gritty technical details check out the Developer Guide
Example Input:
Address1: 27 E Cota St Ste 500
Zipcode: 93101
{
"Addresses":[
{
"Address1":"27 E Cota St Ste 500",
"Address2":"",
"City":"Santa Barbara",
"State":"CA",
"Zip":"93101-7602",
"IsResidential":"false",
"DPV":"1",
"DPVDesc":"Yes, the input record is a valid mailing address",
"DPVNotes":"26,28,39",
"DPVNotesDesc":"The input address matched the ZIP+4 record,The input address matched the DPV record,Highrise apartment\/office building address",
"Corrections":"10,23",
"CorrectionsDesc":"City change,State change",
"BarcodeDigits":"931017602254",
"CarrierRoute":"C006",
"CongressCode":"24",
"CountyCode":"083",
"CountyName":"Santa Barbara",
"FragmentHouse":"27",
"FragmentPreDir":"E",
"FragmentStreet":"Cota",
"FragmentSuffix":"St",
"FragmentPostDir":"",
"FragmentUnit":"Ste",
"Fragment":"500",
"FragmentPMBPrefix":"",
"FragmentPMBNumber":""
}
],
"IsCASS":true
}

Missing amount and order summary in PayPal Express Checkout

I have integrated paypal into codeigniter with paypal_helper (didn't rememeber where I found it, but it is a slightly rewritten version of Paypals original code for express checkout. I try calling this function,
CallShortcutExpressCheckout( $paymentAmount, $currencyCodeType,
$paymentType, $returnURL, $cancelURL)
sending $paymentAmount as int, $currencyCodeType as "NOK" and $paymentType as "Sale".
Both in Sandbox and live, no amount appears on the paypal site...
What could be wrong?
Edit, to further explain my process. I use this, mostly as specified in the https://www.paypal-labs.com/integrationwizard/ecpaypal/cart.php. This should be doable without the form? The paymentAmount could be sent as a standard variable, when calling the function CallShortcutExpressCheckout?:
$resArray = CallShortcutExpressCheckout ($paymentAmount, $currencyCodeType, $paymentType, $returnURL, $cancelURL);
$ack = strtoupper($resArray["ACK"]);
if($ack=="SUCCESS" || $ack=="SUCCESSWITHWARNING")
{
RedirectToPayPal ( $resArray["TOKEN"] );
}
else
{
//Display a user friendly Error on the page using any of the following error information returned by PayPal
$ErrorCode = urldecode($resArray["L_ERRORCODE0"]);
$ErrorShortMsg = urldecode($resArray["L_SHORTMESSAGE0"]);
$ErrorLongMsg = urldecode($resArray["L_LONGMESSAGE0"]);
$ErrorSeverityCode = urldecode($resArray["L_SEVERITYCODE0"]);
echo "SetExpressCheckout API call failed. ";
echo "Detailed Error Message: " . $ErrorLongMsg;
echo "Short Error Message: " . $ErrorShortMsg;
echo "Error Code: " . $ErrorCode;
echo "Error Severity Code: " . $ErrorSeverityCode;
}
The token is saved in a database. The user gets redirected to Paypal, where no amount is listed.
As you're not passing so called 'line item details' (product data), PayPal doesn't display the total amount.
If you only want to show the amount for the current purchase, redirect buyers to https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-xxxxxx&useraction=commit (instead of https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-xxxxx)
If you want to start sending line-item details to PayPal, include the following in your SetExpressCheckout API request:
// Total amount of the purchase, incl shipping, tax, etc
PAYMENTREQUEST_0_AMT=300.0
// Total amount of items purchased, excl shipping, tax, etc
PAYMENTREQUEST_0_ITEMAMT=300.0
// Authorize the funds first (Authorization), or capture immediately (Sale)?
PAYMENTREQUEST_0_PAYMENTACTION=Sale
// First item
L_PAYMENTREQUEST_0_NAME0=Item1
L_PAYMENTREQUEST_0_QTY0=1
L_PAYMENTREQUEST_0_AMT0=100.00
// Second item
L_PAYMENTREQUEST_0_NAME1=Item2
L_PAYMENTREQUEST_0_QTY1=1
L_PAYMENTREQUEST_0_AMT1=200.00
If you want to see this in your own history as well, you'll also need to include this in DoExpressCheckoutPayment.
This was also posted in php paypal express checkout problem
After an extensive reading on messy Paypal docs site this is a short ExpressCheckout guide working on year 2013. I wanted to have item details shown on paypal payment page and merchant transaction history page.
Paypal documentation links
https://developer.paypal.com/webapps/developer/docs/classic/api/
https://developer.paypal.com/webapps/developer/docs/classic/api/merchant/SetExpressCheckout_API_Operation_NVP/
https://developer.paypal.com/webapps/developer/docs/classic/api/merchant/DoExpressCheckoutPayment_API_Operation_NVP/
https://developer.paypal.com/webapps/developer/docs/classic/api/merchant/GetExpressCheckoutDetails_API_Operation_NVP/
You can call following url methods directly on web browser, update token and payerid parameters accordingly.
This is a digital goods so shipping and handling fees are not given. Single item row. Amount and tax fees are given. Do not require a confirmed delivery address, no shipping address fields, no allow freetext note, payer don't need paypal account and no registration required (solutiontype=sole). Activate credit card section on paypal site (landingpage=billing). Use customized brand title on paypal site. Use custom field to give own value for tracking purpose. Merchant site transaction history must show item details (give item details on SetExpressCheckout and DoExpressCheckoutPayment methods).
SetExpressCheckout method opens a new transaction
https://api-3t.sandbox.paypal.com/nvp?
USER=<userid>
&PWD=<pwd>
&SIGNATURE=<mysig>
&METHOD=SetExpressCheckout
&VERSION=98
&PAYMENTREQUEST_0_PAYMENTACTION=SALE
&REQCONFIRMSHIPPING=0
&NOSHIPPING=1
&ALLOWNOTE=0
&SOLUTIONTYPE=Sole
&LANDINGPAGE=Billing
&BRANDNAME=MY+WEBSHOP+TITLE
&PAYMENTREQUEST_0_AMT=22.22
&PAYMENTREQUEST_0_TAXAMT=4.30
&PAYMENTREQUEST_0_ITEMAMT=17.92
&PAYMENTREQUEST_0_DESC=mypurdesc
&PAYMENTREQUEST_0_CUSTOM=custom1
&PAYMENTREQUEST_0_CURRENCYCODE=EUR
&L_PAYMENTREQUEST_0_NUMBER0=itemid1
&L_PAYMENTREQUEST_0_NAME0=MyItem1
&L_PAYMENTREQUEST_0_DESC0=Item1+description
&L_PAYMENTREQUEST_0_QTY0=1
&L_PAYMENTREQUEST_0_AMT0=17.92
&L_PAYMENTREQUEST_0_TAXAMT0=4.30
&RETURNURL=https://myserver.com/webapp/paypal.jsp%3Fcmd=successexp
&CANCELURL=https://myserver.com/webapp/paypal.jsp%3Fcmd=cancelexp
Reply must have ACK=Success or ACK=SuccessWithWarning, read TOKEN value
Redirect user browser to Paypal site, give token value
https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=<token>
User uses paypal account or credit card. Paypal redirects user to return or cancel url.
Redirect destination url gets token and PayerID parameter values.
Transaction is not completed yet we must call doExpressCheckoutPayment method.
Show confirm dialog on screen (with OK, CANCEL button) or simple case
commit a transaction and show "Thank you, purchase completed" message.
User has already accepted a payment in paypal site and expects transaction be finalized.
You may commit transaction within a same request-response handler or using
asynchronous background task. Paypal site may temporarily be unavailable so don't expect it to work immediately.
Commit transaction if redirect was success, use token and payerid
https://api-3t.sandbox.paypal.com/nvp?
USER=<userid>
&PWD=<pwd>
&SIGNATURE=<mysig>
&METHOD=DoExpressCheckoutPayment
&VERSION=98
&PAYMENTREQUEST_0_PAYMENTACTION=SALE
&PAYMENTREQUEST_0_AMT=22.22
&PAYMENTREQUEST_0_TAXAMT=4.30
&PAYMENTREQUEST_0_ITEMAMT=17.92
&PAYMENTREQUEST_0_CURRENCYCODE=EUR
&L_PAYMENTREQUEST_0_NUMBER0=itemid1
&L_PAYMENTREQUEST_0_NAME0=MyItem1
&L_PAYMENTREQUEST_0_QTY0=1
&L_PAYMENTREQUEST_0_AMT0=17.92
&L_PAYMENTREQUEST_0_TAXAMT0=4.30
&token=<token>
&payerid=<payerid>
Read ACK=Success and verify fields
ACK=Success
PAYMENTINFO_0_PAYMENTSTATUS=Completed
PAYMENTINFO_0_ACK=Success
PAYMENTINFO_0_AMT=22.22 total amount must match
PAYMENTINFO_0_FEEAMT=0.99 (just for fun, read paypal comission fee)
PAYMENTINFO_0_CURRENCYCODE=EUR currency must match
(Optional) Read transaction details from Paypal
You can use this during transaction workflow or any time if stored a token for later use.
https://api-3t.sandbox.paypal.com/nvp
?USER=<userid>
&PWD=<pwd>
&SIGNATURE=<mysig>
&METHOD=GetExpressCheckoutDetails
&VERSION=98
&token=<token>
Read response parameters.
ACK=Success
CHECKOUTSTATUS=PaymentActionCompleted
PAYMENTREQUEST_0_AMT=22.22
PAYMENTREQUEST_0_TAXAMT=4.30
PAYMENTREQUEST_0_CURRENCYCODE=EUR
(Optional) Read and save transaction id, correlation id and token id and write to logtable.
PAYMENTREQUEST_0_TRANSACTIONID=11E585715B622391E
CORRELATIONID=4534b683c335f
I'm willing to receive comments if there is any logic errors.
Check this link, hope it helps in some sense:
https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ECGettingStarted
PAYMENTREQUEST_0_AMT=amount //for amount

Resources