PayPal
is one of the best online Payment
transfer service out there. There is no doubt it’s growing day by day with crazy numbers.
I personally have hands on experience with PayPal Java Developer APIs
and would like to share my experience with all my Crunchify readers.
In this tutorial we will use PayPal Java SDK latest version which is 1.14.0
.
Here is a maven dependency for you to add to your Java Eclipse project.
<dependency> <groupId>com.paypal.sdk</groupId> <artifactId>rest-api-sdk</artifactId> <version>LATEST</version> </dependency>
Once you add above PayPal maven dependencies to your Java project then you will see it on your laptop/desktop.
Objective of this tutorial
- Using PayPal API’s you can
put hold
on your customer’s account - Same way you can
capture money
right away for your purchase - You could
refund
your customer using API - Also,
void any hold
you have put on your account before - There are simple steps by which you could perform all above operations and that’s what we will do in this tutorial. Mainly we will put HOLD on customer’s account.
What do I need?
You need PayPal Account. Follow below steps:
- Create
official PayPal
account - Login to PayPal’s developer portal using this link: https://developer.paypal.com/developer/applications
- Create new App using this link: https://developer.paypal.com/developer/applications/create
- Get
ClientID
andClientSecret
which we need in our program to generatepaypalContext
.
Once y0u have ClientID and ClientSecret, next thing is to start writing Java program crunchifyCapturePayPalAPI.java 🙂
Here is a complete logic for this program:
- Create
Payer
object and set PaymentMethod - Set
RedirectUrls
and set cancelURL and returnURL - Set
Details
and Add PaymentDetails - Set
Amount
- Set
Transaction
- Add Payment Details and set Intent to
authorize
- Create APIContext by passing the
clientID
,clientSecret
andmode
- Create
Payment
object and get paymentID - Set
payerID
to PaymentExecution object Execute Payment
and get Authorization
Complete code:
package crunchify.com.paypal.sdk; import java.util.ArrayList; import java.util.List; import com.paypal.api.payments.Amount; import com.paypal.api.payments.Authorization; import com.paypal.api.payments.Details; import com.paypal.api.payments.Links; import com.paypal.api.payments.Payer; import com.paypal.api.payments.Payment; import com.paypal.api.payments.PaymentExecution; import com.paypal.api.payments.RedirectUrls; import com.paypal.api.payments.Transaction; import com.paypal.base.rest.APIContext; import com.paypal.base.rest.PayPalRESTException; /** * @author Crunchify.com * Version: 1.1.0 * */ public class CrunchifyPayPalSDKTutorial { private static String crunchifyID = "<!---- Add your clientID Key here ---->"; private static String crunchifySecret = "<!---- Add your clientSecret Key here ---->"; private static String executionMode = "sandbox"; // sandbox or production public static void main(String args[]) { CrunchifyPayPalSDKTutorial crunchifyObj = new CrunchifyPayPalSDKTutorial(); // How to capture PayPal Payment using Java SDK? doCapture() PayPal SDK call. crunchifyObj.crunchifyCapturePayPalAPI(); } // This is simple API call which will capture a specified amount for any given // Payer or User public void crunchifyCapturePayPalAPI() { /* * Flow would look like this: * 1. Create Payer object and set PaymentMethod * 2. Set RedirectUrls and set cancelURL and returnURL * 3. Set Details and Add PaymentDetails * 4. Set Amount * 5. Set Transaction * 6. Add Payment Details and set Intent to "authorize" * 7. Create APIContext by passing the clientID, secret and mode * 8. Create Payment object and get paymentID * 9. Set payerID to PaymentExecution object * 10. Execute Payment and get Authorization * */ Payer crunchifyPayer = new Payer(); crunchifyPayer.setPaymentMethod("paypal"); // Redirect URLs RedirectUrls crunchifyRedirectUrls = new RedirectUrls(); crunchifyRedirectUrls.setCancelUrl("http://localhost:3000/crunchifyCancel"); crunchifyRedirectUrls.setReturnUrl("http://localhost:3000/crunchifyReturn"); // Set Payment Details Object Details crunchifyDetails = new Details(); crunchifyDetails.setShipping("2.22"); crunchifyDetails.setSubtotal("3.33"); crunchifyDetails.setTax("1.11"); // Set Payment amount Amount crunchifyAmount = new Amount(); crunchifyAmount.setCurrency("USD"); crunchifyAmount.setTotal("6.66"); crunchifyAmount.setDetails(crunchifyDetails); // Set Transaction information Transaction crunchifyTransaction = new Transaction(); crunchifyTransaction.setAmount(crunchifyAmount); crunchifyTransaction.setDescription("Crunchify Tutorial: How to Invoke PayPal REST API using Java Client?"); List<Transaction> crunchifyTransactions = new ArrayList<Transaction>(); crunchifyTransactions.add(crunchifyTransaction); // Add Payment details Payment crunchifyPayment = new Payment(); // Set Payment intent to authorize crunchifyPayment.setIntent("authorize"); crunchifyPayment.setPayer(crunchifyPayer); crunchifyPayment.setTransactions(crunchifyTransactions); crunchifyPayment.setRedirectUrls(crunchifyRedirectUrls); // Pass the clientID, secret and mode. The easiest, and most widely used option. APIContext crunchifyapiContext = new APIContext(crunchifyID, crunchifySecret, executionMode); try { Payment myPayment = crunchifyPayment.create(crunchifyapiContext); System.out.println("createdPayment Obejct Details ==> " + myPayment.toString()); // Identifier of the payment resource created crunchifyPayment.setId(myPayment.getId()); PaymentExecution crunchifyPaymentExecution = new PaymentExecution(); // Set your PayerID. The ID of the Payer, passed in the `return_url` by PayPal. crunchifyPaymentExecution.setPayerId("<!---- Add your PayerID here ---->"); // This call will fail as user has to access Payment on UI. Programmatically // there is no way you can get Payer's consent. Payment createdAuthPayment = crunchifyPayment.execute(crunchifyapiContext, crunchifyPaymentExecution); // Transactional details including the amount and item details. Authorization crunchifyAuthorization = createdAuthPayment.getTransactions().get(0).getRelatedResources().get(0).getAuthorization(); log("Here is your Authorization ID" + crunchifyAuthorization.getId()); } catch (PayPalRESTException e) { // The "standard" error output stream. This stream is already open and ready to // accept output data. System.err.println(e.getDetails()); } } private void log(String string) { System.out.println(string); } }
Eclipse Console Output:
By default PayPal SDK enables DEBUG mode and hence it logs each and every request and response to Eclipse Console.
For detailed information I’ve kept DEBUG mode on and provided detailed result of our getAuthorization Call here.
13:22:28.013 [main] DEBUG com.paypal.base.ConfigManager - sdk_config.properties not present. Skipping... 13:22:28.212 [main] DEBUG com.paypal.base.rest.OAuthTokenCredential - request header: {Authorization=Basic QVNuZG9aaEdGOEg1MFFQSWw5TGl0elhwSDVYTW16YlBwZmxJREFJOGVjUWVwdlJyWVQ4UnBfZUpNQmh1dHJVUHdaZU9CVGJUOE1GRksdfgsdfgsdfg3Q1ZLd0NzZTllRnBIZTNNNWpOR1liNHVxZ3BrNDNFVmFXR2hHNXR2Tk1na1IyZkZMUWdTUmRFY3Q3cG8=, Accept=application/json, User-Agent=PayPalSDK/PayPal-Java-SDK 1.14.0 (v=11; vendor=Oracle Corporation; bit=64; os=Mac_OS_X 10.14.1), Content-Type=application/x-www-form-urlencoded} 13:22:28.212 [main] DEBUG com.paypal.base.rest.OAuthTokenCredential - request body: grant_type=client_credentials 13:22:28.213 [main] DEBUG com.paypal.base.HttpConnection - curl command: curl --verbose --request POST 'https://api.sandbox.paypal.com/v1/oauth2/token' \ --header "Authorization:Basic QVNuZG9aaEdGOEg1MFFQSWw5TGl0elhwSDVYTW16YlBwZmxJREFJOGVjUasdfasdflITlhSZ0xVMGhiOHhpa0M3Q1ZLd0NzZTllRnBIZTNNNWpOR1liNHVxZ3BrNDNFVmFXR2hHNXR2Tk1na1IyZkZMUWdTUmRFY3Q3cG8=" \ --header "Accept:application/json" \ --header "User-Agent:PayPalSDK/PayPal-Java-SDK 1.14.0 (v=11; vendor=Oracle Corporation; bit=64; os=Mac_OS_X 10.14.1)" \ --header "Content-Type:application/x-www-form-urlencoded" \ --data 'grant_type=client_credentials' 13:22:28.810 [main] DEBUG com.paypal.base.rest.OAuthTokenCredential - response header: {paypal-debug-id=[961e2e4122ac1], null=[HTTP/1.1 200 OK], Paypal-Debug-Id=[961e2e4122ac1], Server=[Apache], Connection=[close], Vary=[Authorization], Set-Cookie=[X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT, X-PP-SILOVER=name%3DSANDBOX3.API.1%26silo_version%3D1880%26app%3Dapiplatformproxyserv%26TIME%3D4098358363%26HTTP_X_PP_AZ_LOCATOR%3Dsandbox.slc; Expires=Mon, 26 Nov 2018 19:52:28 GMT; domain=.paypal.com; path=/; Secure; HttpOnly], HTTP_X_PP_AZ_LOCATOR=[sandbox.slc], Content-Length=[876], X-PAYPAL-TOKEN-SERVICE=[IAAS], Date=[Mon, 26 Nov 2018 19:22:28 GMT], Content-Type=[application/json]} 13:22:28.810 [main] DEBUG com.paypal.base.rest.OAuthTokenCredential - response: {"scope":"https://api.paypal.com/v1/payments/.* https://uri.paypal.com/services/payments/refund https://uri.paypal.com/services/applications/webhooks https://uri.paypal.com/services/payments/payment/authcapture https://uri.paypal.com/payments/payouts https://api.paypal.com/v1/vault/credit-card/.* https://uri.paypal.com/services/disputes/read-seller https://uri.paypal.com/services/subscriptions https://uri.paypal.com/services/disputes/read-buyer https://api.paypal.com/v1/vault/credit-card openid https://uri.paypal.com/services/disputes/update-seller https://uri.paypal.com/services/payments/realtimepayment","nonce":"2018-11-26T19:03:03ZymZQ8MNE2MarndZEjUoxwB70puoxUA-NXqc7pUVtVxk","access_token":"A21AAGyWgsdafxUM_1FCE5d9adsfuwfiOB7_4XkX3wKHWXe3nkKgt2bhadflirJsMWP9JAm-pBT2DtUJ5W0A","token_type":"Bearer","app_id":"APP-80W284ads543T","expires_in":31235} 13:22:28.817 [main] DEBUG com.paypal.base.rest.PayPalResource - request header: {Authorization=Bearer A21AAGyWgsdafxUM_1FCE5d9adsfuwfiOB7_4XkX3wKHWXe3nkKgt2bhadflirJsMWP9JAm-pBT2DtUJ5W0A, User-Agent=PayPalSDK/ (v=11; vendor=Oracle Corporation; bit=64; os=Mac_OS_X 10.14.1), PayPal-Request-Id=74886e72-34e4-4a0-8cd7-6adsf63b5dc9, Accept=application/json, Content-Type=application/json} 13:22:28.817 [main] DEBUG com.paypal.base.rest.PayPalResource - request body: { "intent": "sale", "payer": { "payment_method": "paypal" }, "transactions": [ { "amount": { "currency": "USD", "total": "6.66", "details": { "subtotal": "3.33", "shipping": "2.22", "tax": "1.11" } }, "description": "Crunchify Tutorial: How to Invoke PayPal REST API using Java Client?" } ], "redirect_urls": { "return_url": "http://localhost:3000/crunchifyReturn", "cancel_url": "http://localhost:3000/crunchifyCancel" } } 13:22:28.818 [main] DEBUG com.paypal.base.HttpConnection - curl command: curl --verbose --request POST 'https://api.sandbox.paypal.com/v1/payments/payment' \ --header "Authorization:Bearer A21AAGyWgsdafxUM_1FCE5d9adsfuwfiOB7_4XkX3wKHWXe3nkKgt2bhadflirJsMWP9JAm-pBT2DtUJ5W0A" \ --header "User-Agent:PayPalSDK/ (v=11; vendor=Oracle Corporation; bit=64; os=Mac_OS_X 10.14.1)" \ --header "PayPal-Request-Id:74886e72-34e4-4a70-8cd7-605cd63b5dc9" \ --header "Accept:application/json" \ --header "Content-Type:application/json" \ --data '{ "intent": "sale", "payer": { "payment_method": "paypal" }, "transactions": [ { "amount": { "currency": "USD", "total": "6.66", "details": { "subtotal": "3.33", "shipping": "2.22", "tax": "1.11" } }, "description": "Crunchify Tutorial: How to Invoke PayPal REST API using Java Client?" } ], "redirect_urls": { "return_url": "http://localhost:3000/crunchifyReturn", "cancel_url": "http://localhost:3000/crunchifyCancel" } }' 13:22:33.407 [main] DEBUG com.paypal.base.rest.PayPalResource - response: {"id":"PAY-25A74012S3552184CLP6EP6A","intent":"sale","state":"created","payer":{"payment_method":"paypal"},"transactions":[{"amount":{"total":"6.66","currency":"USD","details":{"subtotal":"3.33","tax":"1.11","shipping":"2.22"}},"description":"Crunchify Tutorial: How to Invoke PayPal REST API using Java Client?","related_resources":[]}],"create_time":"2018-11-26T19:22:32Z","links":[{"href":"https://api.sandbox.paypal.com/v1/payments/payment/PAY-25A74012S3552184CLP6EP6A","rel":"self","method":"GET"},{"href":"https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-9C691969F1033220V","rel":"approval_url","method":"REDIRECT"},{"href":"https://api.sandbox.paypal.com/v1/payments/payment/PAY-25A74012S3552184CLP6EP6A/execute","rel":"execute","method":"POST"}]} createdPayment Obejct Details ==> { "id": "PAY-25A74012S3552184CLP6EP6A", "intent": "sale", "payer": { "payment_method": "paypal" }, "transactions": [ { "related_resources": [], "amount": { "currency": "USD", "total": "6.66", "details": { "subtotal": "3.33", "shipping": "2.22", "tax": "1.11" } }, "description": "How to Invoke PayPal REST API using Java Client?" } ], "state": "created", "create_time": "2018-11-26T19:22:32Z", "links": [ { "href": "https://api.sandbox.paypal.com/v1/payments/payment/PAY-25A74012S3552184CLP6EP6A", "rel": "self", "method": "GET" }, { "href": "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd\u003d_express-checkout\u0026token\u003dEC-9C691969F1033220V", "rel": "approval_url", "method": "REDIRECT" }, { "href": "https://api.sandbox.paypal.com/v1/payments/payment/PAY-25A74012S3552184CLP6EP6A/execute", "rel": "execute", "method": "POST" } ] } 13:22:33.414 [main] DEBUG com.paypal.base.rest.PayPalResource - request header: {Authorization=Bearer A21AAGyWgkMoxUM_1FCE5d948J5SAxIuwfiOB7_4XkX3wKHWXe3nkKgt2bhtXISnazHlE9yzlirJsMWP9JAm-pBT2DtUJ5W0A, User-Agent=PayPalSDK/ (v=11; vendor=Oracle Corporation; bit=64; os=Mac_OS_X 10.14.1), PayPal-Request-Id=e47412c8-2c1f-4505-b1a3-7b4723eb99f4, Accept=application/json, Content-Type=application/json} 13:22:33.415 [main] DEBUG com.paypal.base.rest.PayPalResource - request body: { "payer_id": "1Z232AMNN" } 13:22:33.415 [main] DEBUG com.paypal.base.HttpConnection - curl command: curl --verbose --request POST 'https://api.sandbox.paypal.com/v1/payments/payment/PAY-25A74012S3552184CLP6EP6A/execute' \ --header "Authorization:Bearer A21AAGyWgsdafxUM_1FCE5d9adsfuwfiOB7_4XkX3wKHWXe3nkKgt2bhadflirJsMWP9JAm-pBT2DtUJ5W0A" \ --header "User-Agent:PayPalSDK/ (v=11; vendor=Oracle Corporation; bit=64; os=Mac_OS_X 10.14.1)" \ --header "PayPal-Request-Id:eadf412c8-2c1f-4505-b1a3-7basdaf99f4" \ --header "Accept:application/json" \ --header "Content-Type:application/json" \ --data '{ "payer_id": "1Z232AMNN" }' 13:22:34.016 [main] ERROR com.paypal.base.HttpConnection - Response code: 400 Error response: {"name":"PAYMENT_NOT_APPROVED_FOR_EXECUTION","message":"Payer has not approved payment","information_link":"https://developer.paypal.com/docs/api/payments/#errors","debug_id":"113d5208bf8d3"} name: PAYMENT_NOT_APPROVED_FOR_EXECUTION message: Payer has not approved payment details: null debug-id: 113d5208bf8d3 information-link: https://developer.paypal.com/docs/api/payments/#errors
Same way next few tutorials I’l provide more details on how to capture money
, refund money
and void any authorization
you have place on Payer’s account.