Skip to content

Commit 4f9852f

Browse files
authored
feat: add support for php and java server sdk (#158)
1 parent bb12328 commit 4f9852f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1034
-9330
lines changed

advanced-integration/v2/client/html/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ npm install
5757
5858
3. Starting the development server
5959
60-
- **Start the server**: Follow the instructions in the server's README to start it. Typically, this involves running npm run dev or a similar command in the server directory.
60+
- **Start the server**: Follow the instructions in the server's README to start it. Typically, this involves running npm run start or a similar command in the server directory.
6161

6262
- **Start the client**:
6363

6464
```bash
65-
npm run dev
65+
npm run start
6666
```
6767

6868
This will start the development server, and you should be able to access the Advanced Checkout Page in your browser at `http://localhost:3000` (or the port specfied in the terminal output).

advanced-integration/v2/client/html/vite.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default defineConfig({
55
plugins: [],
66
envDir: "../",
77
envPrefix: "PAYPAL",
8-
root: "client",
8+
root: "src",
99
server: {
1010
port: 3000,
1111
proxy: {
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1+
# Create an application to obtain credentials at
2+
# https://developer.paypal.com/dashboard/applications/sandbox
3+
14
PAYPAL_CLIENT_ID=PAYPAL_CLIENT_ID

advanced-integration/v2/client/react/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ npm install
5757
5858
3. Starting the development server
5959
60-
- **Start the server**: Follow the instructions in the server's README to start it. Typically, this involves running npm run dev or a similar command in the server directory.
60+
- **Start the server**: Follow the instructions in the server's README to start it. Typically, this involves running npm run start or a similar command in the server directory.
6161

6262
- **Start the client**:
6363

6464
```bash
65-
npm run dev
65+
npm run start
6666
```
6767

6868
This will start the development server, and you should be able to access the Advanced Checkout Page in your browser at `http://localhost:3000` (or the port specfied in the terminal output).

advanced-integration/v2/client/react/vite.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import react from '@vitejs/plugin-react'
44
// https://vitejs.dev/config/
55
export default defineConfig({
66
plugins: [react()],
7-
root: "client",
7+
root: "src",
88
envDir: "../",
99
envPrefix: "PAYPAL",
1010
server: {

advanced-integration/v2/server/dotnet/README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
# Advanced Integartion .NET Sample
1+
# Advanced Integration .NET Sample
22

33
PayPal Advanced Integration sample in .NET
44

55
## Running the sample
66

77
1. **Add your API credentials to the environment:**
88

9-
- **Windows**
9+
- **Windows (powershell)**
1010

1111
```powershell
1212
$env:PAYPAL_CLIENT_ID = "<PAYPAL_CLIENT_ID>"
1313
$env:PAYPAL_CLIENT_SECRET = "<PAYPAL_CLIENT_SECRET>"
1414
```
1515
16-
- **Unix**
16+
- **Linux / MacOS**
1717
1818
```bash
1919
export PAYPAL_CLIENT_ID="<PAYPAL_CLIENT_ID>"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
java zulu-21.36.19

advanced-integration/v2/server/java/README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
# Advanced Integartion Java Sample
1+
# Advanced Integration Java Sample
22

33
PayPal Advanced Integration sample in Java
44

55
## Running the sample
66

77
1. Add your API credentials to the environment:
88

9-
- **Windows**
9+
- **Windows (powershell)**
1010

1111
```powershell
1212
$env:PAYPAL_CLIENT_ID = "<PAYPAL_CLIENT_ID>"
1313
$env:PAYPAL_CLIENT_SECRET = "<PAYPAL_CLIENT_SECRET>"
1414
```
1515
16-
- **Unix**
16+
- **Linux / MacOS**
1717
1818
```bash
1919
export PAYPAL_CLIENT_ID="<PAYPAL_CLIENT_ID>"

advanced-integration/v2/server/java/pom.xml

+15-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>org.springframework.boot</groupId>
77
<artifactId>spring-boot-starter-parent</artifactId>
8-
<version>3.3.2</version>
8+
<version>3.3.3</version>
99
<relativePath/> <!-- lookup parent from repository -->
1010
</parent>
1111
<groupId>com.paypal.sample</groupId>
@@ -33,10 +33,23 @@
3333
<dependency>
3434
<groupId>org.springframework.boot</groupId>
3535
<artifactId>spring-boot-starter-thymeleaf</artifactId>
36+
<version>3.3.3</version>
3637
</dependency>
3738
<dependency>
3839
<groupId>org.springframework.boot</groupId>
3940
<artifactId>spring-boot-starter-web</artifactId>
41+
<version>3.3.3</version>
42+
</dependency>
43+
<dependency>
44+
<groupId>
45+
com.paypal.sdk
46+
</groupId>
47+
<artifactId>
48+
paypal-server-sdk
49+
</artifactId>
50+
<version>
51+
0.5.1
52+
</version>
4053
</dependency>
4154
</dependencies>
4255

@@ -45,6 +58,7 @@
4558
<plugin>
4659
<groupId>org.springframework.boot</groupId>
4760
<artifactId>spring-boot-maven-plugin</artifactId>
61+
<version>3.3.3</version>
4862
</plugin>
4963
</plugins>
5064
</build>
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,37 @@
11
package com.paypal.sample;
22

3-
import com.fasterxml.jackson.databind.JsonNode;
43
import com.fasterxml.jackson.databind.ObjectMapper;
5-
import com.fasterxml.jackson.databind.node.ObjectNode;
64
import org.springframework.beans.factory.annotation.Value;
75
import org.springframework.boot.SpringApplication;
86
import org.springframework.boot.autoconfigure.SpringBootApplication;
97
import org.springframework.context.annotation.Bean;
108

11-
import org.springframework.http.HttpEntity;
12-
import org.springframework.http.HttpHeaders;
139
import org.springframework.http.HttpStatus;
14-
import org.springframework.http.MediaType;
1510
import org.springframework.http.ResponseEntity;
1611
import org.springframework.stereotype.Controller;
17-
import org.springframework.util.LinkedMultiValueMap;
18-
import org.springframework.util.MultiValueMap;
19-
2012
import org.springframework.web.bind.annotation.PathVariable;
2113
import org.springframework.web.bind.annotation.PostMapping;
2214
import org.springframework.web.bind.annotation.RequestBody;
2315
import org.springframework.web.bind.annotation.RequestMapping;
2416
import org.springframework.web.client.RestTemplate;
2517

18+
import com.paypal.sdk.Environment;
19+
import com.paypal.sdk.PaypalServerSDKClient;
20+
import com.paypal.sdk.authentication.ClientCredentialsAuthModel;
21+
import com.paypal.sdk.controllers.OrdersController;
22+
import com.paypal.sdk.exceptions.ApiException;
23+
import com.paypal.sdk.http.response.ApiResponse;
24+
import com.paypal.sdk.models.AmountWithBreakdown;
25+
import com.paypal.sdk.models.CheckoutPaymentIntent;
26+
import com.paypal.sdk.models.Order;
27+
import com.paypal.sdk.models.OrderRequest;
28+
import com.paypal.sdk.models.OrdersCaptureInput;
29+
import com.paypal.sdk.models.OrdersCreateInput;
30+
import com.paypal.sdk.models.PurchaseUnitRequest;
31+
import java.util.Arrays;
32+
import org.slf4j.event.Level;
33+
2634
import java.io.IOException;
27-
import java.util.Base64;
2835
import java.util.Map;
2936

3037
@SpringBootApplication
@@ -36,8 +43,6 @@ public class SampleAppApplication {
3643
@Value("${PAYPAL_CLIENT_SECRET}")
3744
private String PAYPAL_CLIENT_SECRET;
3845

39-
private final String BASE_URL = "https://api-m.sandbox.paypal.com";
40-
4146
public static void main(String[] args) {
4247
SpringApplication.run(SampleAppApplication.class, args);
4348
}
@@ -47,23 +52,41 @@ public RestTemplate restTemplate() {
4752
return new RestTemplate();
4853
}
4954

55+
@Bean
56+
public PaypalServerSDKClient paypalClient() {
57+
return new PaypalServerSDKClient.Builder()
58+
.loggingConfig(builder -> builder
59+
.level(Level.DEBUG)
60+
.requestConfig(logConfigBuilder -> logConfigBuilder.body(true))
61+
.responseConfig(logConfigBuilder -> logConfigBuilder.headers(true)))
62+
.httpClientConfig(configBuilder -> configBuilder
63+
.timeout(0))
64+
.environment(Environment.SANDBOX)
65+
.clientCredentialsAuth(new ClientCredentialsAuthModel.Builder(
66+
PAYPAL_CLIENT_ID,
67+
PAYPAL_CLIENT_SECRET)
68+
.build())
69+
.build();
70+
}
71+
72+
5073
@Controller
5174
@RequestMapping("/")
5275
public class CheckoutController {
5376

54-
private final RestTemplate restTemplate;
5577
private final ObjectMapper objectMapper;
78+
private final PaypalServerSDKClient client;
5679

57-
public CheckoutController(RestTemplate restTemplate, ObjectMapper objectMapper) {
58-
this.restTemplate = restTemplate;
80+
public CheckoutController(ObjectMapper objectMapper, PaypalServerSDKClient client) {
5981
this.objectMapper = objectMapper;
82+
this.client = client;
6083
}
6184

6285
@PostMapping("/api/orders")
63-
public ResponseEntity<JsonNode> createOrder(@RequestBody Map<String, Object> request) {
86+
public ResponseEntity<Order> createOrder(@RequestBody Map<String, Object> request) {
6487
try {
6588
String cart = objectMapper.writeValueAsString(request.get("cart"));
66-
JsonNode response = createOrder(cart);
89+
Order response = createOrder(cart);
6790
return new ResponseEntity<>(response, HttpStatus.OK);
6891
} catch (Exception e) {
6992
e.printStackTrace();
@@ -72,69 +95,47 @@ public ResponseEntity<JsonNode> createOrder(@RequestBody Map<String, Object> req
7295
}
7396

7497
@PostMapping("/api/orders/{orderID}/capture")
75-
public ResponseEntity<JsonNode> captureOrder(@PathVariable String orderID) {
98+
public ResponseEntity<Order> captureOrder(@PathVariable String orderID) {
7699
try {
77-
JsonNode response = captureOrders(orderID);
78-
return new ResponseEntity<>(response, HttpStatus.OK);
100+
Order response = captureOrders(orderID);
101+
return new ResponseEntity<Order>(response, HttpStatus.OK);
79102
} catch (Exception e) {
80103
e.printStackTrace();
81104
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
82105
}
83106
}
84107

85-
private String generateAccessToken() throws IOException {
86-
if (PAYPAL_CLIENT_ID == null || PAYPAL_CLIENT_SECRET == null) {
87-
throw new IllegalArgumentException("MISSING_API_CREDENTIALS");
88-
}
89-
String auth = Base64.getEncoder().encodeToString((PAYPAL_CLIENT_ID + ":" + PAYPAL_CLIENT_SECRET).getBytes());
90-
HttpHeaders headers = new HttpHeaders();
91-
headers.setBasicAuth(auth);
92-
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
93-
94-
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
95-
body.add("grant_type", "client_credentials");
96-
97-
ResponseEntity<JsonNode> response = restTemplate.postForEntity(BASE_URL + "/v1/oauth2/token", new HttpEntity<>(body, headers), JsonNode.class);
98-
return response.getBody().get("access_token").asText();
99-
}
100-
101-
private JsonNode createOrder(String cart) throws IOException {
102-
String accessToken = generateAccessToken();
103-
String url = BASE_URL + "/v2/checkout/orders";
108+
private Order createOrder(String cart) throws IOException, ApiException {
104109

105-
ObjectNode payload = objectMapper.createObjectNode();
106-
payload.put("intent", "CAPTURE");
107-
ObjectNode purchaseUnit = payload.putArray("purchase_units").addObject();
108-
ObjectNode amount = purchaseUnit.putObject("amount");
109-
amount.put("currency_code", "USD");
110-
amount.put("value", "100.00");
110+
OrdersCreateInput ordersCreateInput = new OrdersCreateInput.Builder(
111+
null,
112+
new OrderRequest.Builder(
113+
CheckoutPaymentIntent.CAPTURE,
114+
Arrays.asList(
115+
new PurchaseUnitRequest.Builder(
116+
new AmountWithBreakdown.Builder(
117+
"USD",
118+
"100.00")
119+
.build())
120+
.build()))
121+
.build())
122+
.build();
111123

112-
HttpHeaders headers = new HttpHeaders();
113-
headers.setBearerAuth(accessToken);
114-
headers.setContentType(MediaType.APPLICATION_JSON);
124+
OrdersController ordersController = client.getOrdersController();
115125

116-
ResponseEntity<JsonNode> response = restTemplate.postForEntity(url, new HttpEntity<>(payload, headers), JsonNode.class);
117-
return handleResponse(response);
118-
}
119-
120-
private JsonNode captureOrders(String orderID) throws IOException {
121-
String accessToken = generateAccessToken();
122-
String url = BASE_URL + "/v2/checkout/orders/" + orderID + "/capture";
126+
ApiResponse<Order> apiResponse = ordersController.ordersCreate(ordersCreateInput);
123127

124-
HttpHeaders headers = new HttpHeaders();
125-
headers.setBearerAuth(accessToken);
126-
headers.setContentType(MediaType.APPLICATION_JSON);
127-
128-
ResponseEntity<JsonNode> response = restTemplate.postForEntity(url, new HttpEntity<>(headers), JsonNode.class);
129-
return handleResponse(response);
128+
return apiResponse.getResult();
130129
}
131130

132-
private JsonNode handleResponse(ResponseEntity<JsonNode> response) throws IOException {
133-
if (response.getStatusCode().is2xxSuccessful()) {
134-
return response.getBody();
135-
} else {
136-
throw new IOException(response.getBody().toString());
137-
}
131+
private Order captureOrders(String orderID) throws IOException, ApiException {
132+
OrdersCaptureInput ordersCaptureInput = new OrdersCaptureInput.Builder(
133+
orderID,
134+
null)
135+
.build();
136+
OrdersController ordersController = client.getOrdersController();
137+
ApiResponse<Order> apiResponse = ordersController.ordersCapture(ordersCaptureInput);
138+
return apiResponse.getResult();
138139
}
139140
}
140141
}

advanced-integration/v2/server/node/README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
# Advanced Integartion Node.js Sample
1+
# Advanced Integration Node.js Sample
22

33
PayPal Advanced Integration sample in Node.js
44

55
## Running the sample
66

77
1. Add your API credentials to the environment:
88

9-
- **Windows**
9+
- **Windows (powershell)**
1010

1111
```powershell
1212
$env:PAYPAL_CLIENT_ID = "<PAYPAL_CLIENT_ID>"
1313
$env:PAYPAL_CLIENT_SECRET = "<PAYPAL_CLIENT_SECRET>"
1414
```
1515
16-
- **Unix**
16+
- **Linux / MacOS**
1717
1818
```bash
1919
export PAYPAL_CLIENT_ID="<PAYPAL_CLIENT_ID>"

advanced-integration/v2/server/node/package.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@
44
"private": true,
55
"type": "module",
66
"dependencies": {
7+
"@paypal/paypal-server-sdk": "^0.5.1",
8+
"body-parser": "^1.20.3",
79
"dotenv": "^16.3.1",
8-
"express": "^4.18.2",
9-
"node-fetch": "^3.3.2"
10+
"express": "^4.18.2"
1011
},
1112
"scripts": {
12-
"server-dev": "nodemon server/server.js",
13+
"server-dev": "nodemon server.js",
1314
"start": "npm run server-dev",
14-
"prod": "node server/server.js",
15+
"prod": "node server.js",
1516
"format": "npx prettier --write **/*.{js,jsx,md}",
1617
"format:check": "npx prettier --check **/*.{js,jsx,md}"
1718
},

0 commit comments

Comments
 (0)