问题
We are using PayPal future payments in our IOS app. We need to know email ID of the account that has authorized future payment. How can we fetch email ID of the user who has authorized future payment. Current API operation for approval returns only authorization token.
回答1:
I'm assuming by "future payments" you're referring to Preapproved Payments..??
Setup an IPN solution and make sure to an IPNNotificationURL in your Preapproval API request. The IPN will include more details about the transaction including the payer email address.
Here is a list of the variables you can expect from a Preapproval profile getting created. You'll notice the "sender_email" parameter, which is what you'd be looking for.
Here's a sample of an actual IPN I got in the sandbox after processing a Preapproval request.
Array
(
[max_number_of_payments] => 100
[starting_date] => 2015-03-01T00:00:21.000-08:00
[pin_type] => NOT_REQUIRED
[max_amount_per_payment] => 20.00
[currency_code] => USD
[sender_email] => guy.louzon-buyer@gmail.com
[verify_sign] => AFcWxV21C7fd0v3bYYYRCpSSRl31AiHQSQchSGUInXdtl6zomfkZ7H4C
[test_ipn] => 1
[date_of_month] => 0
[current_number_of_payments] => 0
[preapproval_key] => PA-2M0807730Y425554F
[ending_date] => 2015-12-31T23:59:21.000-08:00
[approved] => true
[transaction_type] => Adaptive Payment PREAPPROVAL
[day_of_week] => NO_DAY_SPECIFIED
[status] => ACTIVE
[current_total_amount_of_all_payments] => 0.00
[current_period_attempts] => 0
[charset] => windows-1252
[payment_period] => 0
[notify_version] => UNVERSIONED
[max_total_amount_of_all_payments] => 2000.00
)
回答2:
Ichathan, you'll want to utilize the Profile Sharing feature of the mSDK to get the customer attributes and pass in the Future Payment scope within that to also gain consent for those. The available scopes you can use for Profile Sharing are listed out in the PayPalOAuthScopes.h file of the iOS SDK.
回答3:
This answer is correct but not detailed.
The Profile Sharing Mobile Integration allows the user to consent to future payments as well as gets email and other information in one login flow. Here's the snippet we used:
func profileController() -> PayPalProfileSharingViewController {
PayPalMobile.preconnectWithEnvironment(PayPalEnvironmentSandbox)//PayPalEnvironmentNoNetwork)
let scope: Set<String> = Set([kPayPalOAuth2ScopeEmail, kPayPalOAuth2ScopeFuturePayments])
let controller = PayPalProfileSharingViewController(scopeValues: scope, configuration: self.paypalConfiguration!, delegate: self)
return controller!
}
func payPalProfileSharingViewController(profileSharingViewController: PayPalProfileSharingViewController, userDidLogInWithAuthorization profileSharingAuthorization: [NSObject : AnyObject]) {
self.processAuthorization(profileSharingAuthorization)
}
func userDidCancelPayPalProfileSharingViewController(profileSharingViewController: PayPalProfileSharingViewController) {
self.delegate?.didFailPayPalConsent()
}
func processAuthorization(authorization: [NSObject: AnyObject]) {
if let authCode = authorization["response"]?["code"] as? String {
self.delegate?.didSucceedPayPalConsent(authCode)
}
else {
self.delegate?.didFailPayPalConsent()
}
}
Edit: The mobile controller gives you the auth token that has permissions for profile information, but you have to make another call from your server side code for that information:
https://developer.paypal.com/docs/api/#get-user-information
回答4:
This is how I did it. The profile sharing Paypal Profile Sharing gives us the Auth Token This particular delegate function gets called
func payPalProfileSharingViewController(profileSharingViewController: PayPalProfileSharingViewController, userDidLogInWithAuthorization profileSharingAuthorization: [NSObject : AnyObject]) {
self.processAuthorization(profileSharingAuthorization)
}
After authToken we need to hit some server side APIs . We can achieve this through app side as well. I have hit server side apis from client side
First step is to make a basic Auth Request it will return us a Refresh as well as Access Token. Get Access Token
func generateAccessToken(authCode : String ,block : completionHandler){
let parameters = ["grant_type" : "authorization_code", "response_type" :"token","redirect_uri" : "urn:ietf:wg:oauth:2.0:oob","code":authCode]
let username = AppConstants().kPayPalUserName //APP_ID
let password = AppConstants().kPayPalSecret
let credentialData = "\(username):\(password)".data(using: String.Encoding.utf8)!
let base64Credentials = credentialData.base64EncodedString(options: [])
let headers = ["Authorization": "Basic \(base64Credentials)"]
let customerURL = AppConstants().kPayPalUrl
Alamofire.request(customerURL,
method: .post,
parameters: parameters,
encoding: URLEncoding.default,
headers:headers)
.validate()
.responseJSON { response in
switch response.result {
case .success(let value):
KVNProgress.dismiss(completion: {
block?(true, value as! Dictionary<String, Any>) // get the accessToken
})
// BasicFunctions.displayAlert("Success", needDismiss: false, title: "Task Created Successfully")
case .failure(let responseError):
KVNProgress.dismiss(completion: {
if (responseError != nil) {
BasicFunctions.displayAlert(SERVER_ERROR)
// let json = JSONSerialization
// block!(false,responseError as! Dictionary<String, Any>)
}else{
BasicFunctions.displayAlert(SERVER_ERROR)
}
})
}
}
}
Using the access Token we need to hit another CURL request and it will give us all the user information Get User Profile Information
Now using this request we can get complete user info. The access Token was generated from Basic Auth Token
func getUserProfileInfo(accessToken : String,block : completionHandler){
KVNProgress.show()
let parameters = ["":""]
let headers = ["Authorization": "Bearer " + accessToken]
let customerURL = "https://api.sandbox.paypal.com/v1/identity/openidconnect/userinfo/?schema=openid"
Alamofire.request(customerURL, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON { (response) in
switch response.result {
case .success(let value):
KVNProgress.dismiss(completion: {
block?(true, value as! Dictionary<String, Any>)
})
// BasicFunctions.displayAlert("Success", needDismiss: false, title: "Task Created Successfully")
case .failure(let responseError):
KVNProgress.dismiss(completion: {
if (responseError != nil) {
BasicFunctions.displayAlert(SERVER_ERROR)
// let json = JSONSerialization
// block!(false,responseError as! Dictionary<String, Any>)
}else{
BasicFunctions.displayAlert(SERVER_ERROR)
}
})
}
}
}
Note : Make sure in your app settings in Paypal You have allowed access to email or other user information
Disclaimer : This project was only for a POC so I am not sure whether we are violating the PCI compliance by hitting server side APIs from client side
来源:https://stackoverflow.com/questions/28425355/paypal-email-id-of-the-user-who-has-approved-future-payment