上一篇文章 java對接PayPal支付(v2). 講了PayPal v2:checkout-sdk 的對接過程,今天我們講講如何通過代碼對已經發貨的訂單添加物流資訊。
為何要添加物流資訊?
上一邊文章已經提到過了,通過PayPal支付的訂單,一旦出現争議,PayPal大多數時候是偏向使用者的,商戶這邊如果再各個細節上處理的不好,會導緻貨、錢兩空的局面。為了防止這種情況,添加物流資訊可避免使用者惡意發起沒有收到貨物的争議。
言歸正傳,正式開始
一、引入maven依賴
這次我們必須引入 v1 rest-api-sdk,目的是為了擷取token,如果你不想再引入這個maven的話,也是可以的,自己根據PayPal官網的文檔,寫個http請求,擷取token也行,下面這幅圖就是擷取curl的方式
<dependency>
<groupId>com.paypal.sdk</groupId>
<artifactId>rest-api-sdk</artifactId>
<version>LATEST</version>
</dependency>
二、編寫代碼
1、AddTracking(添加物流資訊)
由于官方并沒有将添加物流資訊的接口融入SDK,是以我們需要自己寫http請求,進行請求通路。
package com.ratta.paypal.info;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSONObject;
import com.paypal.base.rest.OAuthTokenCredential;
import com.paypal.base.rest.PayPalRESTException;
import com.paypal.http.HttpResponse;
import com.paypal.orders.Order;
import com.paypal.orders.OrdersGetRequest;
import com.ratta.util.HttpUtil;
public class AddTracking {
private String clientId = "AdTJ2en6Av42r1xoziJj6bJK-X4tRGDHACZId0OPXfGyXs8OyoYEmlm8bHjzrgd3UislDQR0iBP7x-wM";
private String clientSecret = "EC9DSrfAfVfo-c3K-1dILXA5iijnHtaunKwv2JzECSz9jcdy3t78rDFeAEgaixnnIYYlgQcipbZQWoCa";
private String mode = "sandbox";
private static String sandbox = "https://api.sandbox.paypal.com";
private static String live = "https://api.paypal.com";
private static String url = "/v1/shipping/trackers-batch";
public TrackingInfo buildRequestBody(String captureId) {
TrackingInfo trackingInfo = new TrackingInfo();
trackingInfo.setTransaction_id(captureId);
//物流單号
trackingInfo.setTracking_number("443844607822");
return trackingInfo;
}
public String addTrack(String orderId) throws PayPalRESTException, IOException {
OrdersGetRequest ordersGetRequest = new OrdersGetRequest(orderId);
PayPalClient payPalClient = new PayPalClient();
HttpResponse<Order> ordersGetResponse = payPalClient.client(mode, clientId, clientSecret).execute(ordersGetRequest);
String captureId = ordersGetResponse.result().purchaseUnits().get(0).payments().captures().get(0).id();
System.out.println("Status Code: " + ordersGetResponse.statusCode());
System.out.println("Status: " + ordersGetResponse.result().status());
System.out.println("Order id: " + ordersGetResponse.result().id());
System.out.println("Capture id: " + captureId);
Map<String, String> configurationMap = new HashMap<String, String>();
configurationMap.put("service.EndPoint", "live".equals(mode)? live : sandbox);
OAuthTokenCredential merchantTokenCredential = new OAuthTokenCredential(
clientId, clientSecret, configurationMap);
String accessToken = merchantTokenCredential.getAccessToken();
System.out.println("token = " + accessToken);
Map<String, Object> params = new HashMap<String, Object>();
ArrayList<TrackingInfo> list = new ArrayList<TrackingInfo>();
TrackingInfo trackingInfo = new TrackingInfo();
trackingInfo = buildRequestBody(captureId);
list.add(trackingInfo);
params.put("trackers", list);
JSONObject json = new JSONObject(params);
String result = HttpUtil.doPost("live".equals(mode)? live + url : sandbox + url, json.toString(), accessToken);
System.out.println("result = " + result);
return result;
}
public static void main(String[] args) {
try {
new AddTracking().addTrack("訂單id,CreateOrder 生成");
} catch (Exception e) {
e.printStackTrace();
}
}
}
2、TrackingInfo(物流資訊主體)
package com.ratta.paypal.info;
import java.io.Serializable;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class TrackingInfo implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String transaction_id;
private String tracking_number;
/**
* DELIVERED、CANCELLED 退款被拒絕
* SHIPPED 已發貨
* DROPPED_OFF 已嘗試發放退款
* IN_TRANSIT 已轉賬
*/
private String status = "SHIPPED";
/**
* DHL DHL Express
* FEDEX
* 更多物流公司代碼,參考官網
*/
private String carrier = "FEDEX";
}
3、HttpUtil
package com.ratta.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import com.alibaba.csp.sentinel.util.StringUtil;
public class HttpUtil {
private static final String ENCODING = "UTF-8";
public static String doGet(String httpurl) {
HttpURLConnection connection = null;
InputStream is = null;
BufferedReader br = null;
String result = null;// 傳回結果字元串
try {
// 建立遠端url連接配接對象
URL url = new URL(httpurl);
// 通過遠端url連接配接對象打開一個連接配接,強轉成httpURLConnection類
connection = (HttpURLConnection) url.openConnection();
// 設定連接配接方式:get
connection.setRequestMethod("GET");
// 設定連接配接主機伺服器的逾時時間:15000毫秒
connection.setConnectTimeout(15000);
// 設定讀取遠端傳回的資料時間:60000毫秒
connection.setReadTimeout(60000);
// 發送請求
connection.connect();
// 通過connection連接配接,擷取輸入流
if (connection.getResponseCode() == 200) {
is = connection.getInputStream();
// 封裝輸入流is,并指定字元集
br = new BufferedReader(new InputStreamReader(is, ENCODING));
// 存放資料
StringBuffer sbf = new StringBuffer();
String temp = null;
while ((temp = br.readLine()) != null) {
sbf.append(temp);
sbf.append("\r\n");
}
result = sbf.toString();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 關閉資源
if (null != br) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != is) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
connection.disconnect();// 關閉遠端連接配接
}
return result;
}
public static String doPost(String httpUrl, String param, String authorization) {
HttpURLConnection connection = null;
InputStream is = null;
OutputStream os = null;
BufferedReader br = null;
String result = null;
try {
URL url = new URL(httpUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setConnectTimeout(15000);
connection.setReadTimeout(60000);
// 預設值為:false,當向遠端伺服器傳送資料/寫資料時,需要設定為true
connection.setDoOutput(true);
// 預設值為:true,目前向遠端服務讀取資料時,設定為true,該參數可有可無
connection.setDoInput(true);
// 設定傳入參數的格式:請求參數應該是 name1=value1&name2=value2 的形式。
connection.setRequestProperty("Content-Type", "application/json");
// 設定鑒權資訊:Authorization: Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0
if(!StringUtil.isEmpty(authorization)) {
connection.setRequestProperty("Authorization", authorization);
}
// 通過連接配接對象擷取一個輸出流
os = connection.getOutputStream();
// 通過輸出流對象将參數寫出去/傳輸出去,它是通過位元組數組寫出的
os.write(param.getBytes());
// 通過連接配接對象擷取一個輸入流,向遠端讀取
if (connection.getResponseCode() == 200) {
is = connection.getInputStream();
// 對輸入流對象進行包裝:charset根據工作項目組的要求來設定
br = new BufferedReader(new InputStreamReader(is, ENCODING));
StringBuffer sbf = new StringBuffer();
String temp = null;
// 循環周遊一行一行讀取資料
while ((temp = br.readLine()) != null) {
sbf.append(temp);
sbf.append("\r\n");
}
result = sbf.toString();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 關閉資源
if (null != br) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != os) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != is) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 斷開與遠端位址url的連接配接
connection.disconnect();
}
return result;
}
public static void main(String[] args) {
}
}
不引入v1的maven依賴時。擷取token
public static void main(String[] args) {
String clientId = "AdTJ2en6Av42r1xoziJj6bJK-X4tRGDHACZId0OPXfGyXs8OyoYEmlm8bHjzrgd3UislDQR0iBP7x-wM";
String clientSecret = "EC9DSrfAfVfo-c3K-1dILXA5iijnHtaunKwv2JzECSz9jcdy3t78rDFeAEgaixnnIYYlgQcipbZQWoCa";
String authString = clientId + ":" + clientSecret;
System.out.println("auth string: " + authString);
//Base64編碼
byte[] authEncBytes = null;
try {
authEncBytes = Base64.encodeBase64(authString.getBytes("utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String authStringEnc = new String(authEncBytes);
authStringEnc = "Basic " + authStringEnc;
String param = "grant_type=client_credentials";
String result = HttpUtil.doPost("https://api.sandbox.paypal.com/v1/oauth2/token", param, authStringEnc);
System.out.println("result = " + result);
Map map = JSON.parseObject(result);
String accessToken = (String) map.get("access_token");
accessToken = (String) map.get("token_type") + " " + accessToken;
System.out.println("token = " + accessToken);
}
添加完物流資訊後,PayPal訂單這裡就會如圖這樣顯示