Ủy quyền và xác thực
Ủy quyền là bước quan trọng để sử dụng Open API. Bạn cần được người bán ủy quyền để ứng dụng của bạn có thể gọi các API không công khai cần thiết cho việc quản lý cửa hàng.
Bạn sẽ được xác thực dựa trên các tham số chung được truyền vào Open API. Nếu xác thực thất bại, lời gọi của bạn sẽ thất bại và một lỗi sẽ được trả về.
| ⚠️ Lưu ý - Thời hạn ủy quyền Mỗi lần ủy quyền có thể được đặt cho khoảng thời gian tối đa 365 ngày. Sau khi ủy quyền hết hạn, bạn cần liên hệ người bán để ủy quyền lại cho ứng dụng của bạn. Lưu ý: Thời hạn hiệu lực là tùy chọn, nhưng không thể vượt quá 365 ngày. - Ủy quyền cửa hàng SIP Khi cửa hàng Chính SIP cấp ủy quyền cho một ứng dụng, tất cả các cửa hàng Liên kết SIP của nó sẽ tự động được cấp ủy quyền. Lưu ý rằng các cửa hàng Liên kết SIP có quyền gọi API hạn chế so với cửa hàng Chính. |
Quy trình ủy quyền
Có 4 bước để hoàn tất ủy quyền: Tạo liên kết ủy quyền, lấy ủy quyền từ (các) cửa hàng, sử dụng mã ủy quyền, và lấy và làm mới access_token.
Những bước này sẽ được giải thích chi tiết bên dưới, cùng với thông tin về những gì cần chuẩn bị trước khi ủy quyền, chi tiết của quy trình ủy quyền, và cách sử dụng thông tin được trả về sau ủy quyền để vượt qua xác thực của nền tảng.
Tạo liên kết ủy quyền
Đối với ứng dụng Hệ thống nội bộ người bán, bạn có thể đăng nhập vào Open Platform > Danh sách ứng dụng > nhấp Ủy quyền > điền Redirect URL để tạo liên kết ủy quyền.

Đối với tất cả loại ứng dụng, bạn cần tạo liên kết ủy quyền với các thông số kỹ thuật sau. Liên kết ủy quyền bao gồm URL ủy quyền cố định và các tham số bắt buộc khác.
URL ủy quyền cố định:
Môi trường thực:
https://partner.shopeemobile.com/api/v2/shop/auth\_partner
(Trung Quốc đại lục)https://openplatform.shopee.cn/api/v2/shop/auth\_partner
Môi trường kiểm thử sandbox:
https://openplatform.sandbox.test-stable.shopee.sg/api/v2/shop/auth\_partner
(Trung Quốc đại lục) https://openplatform.sandbox.test-stable.shopee.cn/api/v2/shop/auth\_partner
Các tham số bắt buộc khác:
| Tên tham số | Loại | Mô tả |
|---|---|---|
| sign | string | Chữ ký lấy được bằng cách băm chuỗi cơ sở (thứ tự: partner_id, api path, timestamp...) với HMAC-SHA256 sử dụng partner_key. |
| partner_id | int | partner_id lấy từ ứng dụng. |
| timestamp | int | Phải giống với timestamp được dùng trong chuỗi cơ sở của sign. Timestamp chỉ có hiệu lực trong 5 phút. |
| redirect | string | URL mà trang web chuyển hướng đến sau khi hoàn tất ủy quyền. Có thể là bất kỳ URL nào, chẳng hạn như trang web chính thức của công ty bạn. |
Tính toán tham số sign
Tham số sign không chỉ là thành phần của liên kết ủy quyền mà còn là tham số dùng để xác thực mỗi lần gọi. Phần này sẽ giải thích cách tạo chuỗi cơ sở sign và tính chữ ký xác thực thông qua HMAC-SHA256.
Tạo chuỗi cơ sở sign
Có 3 loại API yêu cầu sử dụng các tham số khác nhau để tạo chuỗi cơ sở sign (nhất quán với các tham số chung của nó).
Ghép nối đường dẫn API (không bao gồm host) và các tham số chung bên dưới thành một chuỗi cơ sở sign duy nhất theo thứ tự sau:
- Đối với Shop API: partner_id, api path, timestamp, access_token, shop_id
- Đối với Merchant API: partner_id, api path, timestamp, access_token, merchant_id
- Đối với Public API: partner_id, api path, timestamp
Tính chữ ký xác thực
Sử dụng HMAC-SHA256 để băm chuỗi cơ sở sign, và sử dụng partner key làm khóa mã hóa. Giá trị băm thập lục phân viết thường là chữ ký xác thực.
Demo code Python:
Python
import hmac
import json
import time
import requests
import hashlib
def shop_auth():
timest = int(time.time())
host = "https://partner.shopeemobile.com"
path = "/api/v2/shop/auth_partner"
redirect_url = "https://www.baidu.com/"
partner_id = 80001
tmp = "test...."
partner_key = tmp.encode()
tmp_base_string = "%s%s%s" % (partner_id, path, timest)
base_string = tmp_base_string.encode()
sign = hmac.new(partner_key, base_string, hashlib.sha256).hexdigest()
##generate api
url = host + path + "?partner_id=%s×tamp=%s&sign=%s&redirect=%s" % (partner_id, timest, sign, redirect_url)
print(url)
Demo code Go:
Go
func auth_shop(){
timest := strconv.FormatInt(time.Now().Unix(),10)
host := "https://openplatform.sandbox.test-stable.shopee.sg"
path := "/api/v2/shop/auth_partner"
redirectUrl := "https://www.baidu.com/"
partnerId := strconv.Itoa(2006566)
partnerKey := "1391fd986fe8ec7569bebed75b0c33ee35eb5a305bed7038657a5cd5f75b1c88"
baseString := fmt.Sprintf("%s%s%s", partnerId,path,timest)
h := hmac.New(sha256.New,[]byte(partnerKey))
h.Write([]byte(baseString))
sign := hex.EncodeToString(h.Sum(nil))
url := fmt.Sprintf(host+path+"?partner_id=%s×tamp=%s&sign=%s&redirect=%s", partnerId,timest,sign, redirectUrl)
fmt.Println(url)
}
Demo code Java:
Java
//generate auth url
public static void shop_auth(){
long timest = System.currentTimeMillis() / 1000L;
String host = "https://partner.shopeemobile.com";
String path = "/api/v2/shop/auth_partner";
String redirect_url = "https://www.baidu.com/";
long partner_id = 123456L;
String tmp_partner_key = "...";
String tmp_base_string = String.format("%s%s%s", partner_id, path, timest);
byte[] partner_key;
byte[] base_string;
String sign = "";
try {
base_string = tmp_base_string.getBytes("UTF-8");
partner_key = tmp_partner_key.getBytes("UTF-8");
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(partner_key, "HmacSHA256");
mac.init(secret_key);
sign = String.format("%064x",new BigInteger(1,mac.doFinal(base_string)));
} catch (Exception e) {
e.printStackTrace();
}
String url = host + path + String.format("?partner_id=%s×tamp=%s&sign=%s&redirect=%s", partner_id,timest, sign, redirect_url);
System.out.println(url);
}
Demo code PHP:
PHP
<?php
function authShop($partnerId, $partnerKey) {
global $host;
$path = "/api/v2/shop/auth_partner";
$redirectUrl = "https://www.baidu.com/";
$timest = time();
$baseString = sprintf("%s%s%s", $partnerId, $path, $timest);
$sign = hash_hmac('sha256', $baseString, $partnerKey);
$url = sprintf("%s%s?partner_id=%s×tamp=%s&sign=%s&redirect=%s", $host, $path, $partnerId, $timest, $sign, $redirectUrl);
return $url;
}
$host="https://openplatform.sandbox.test-stable.shopee.sg";
$partnerId = 847892;
$partnerKey = "57615053704d6470644f554a78656d50484143644964436a5568777544524579";
echo authShop($partnerId, $partnerKey);
?>
Ví dụ về liên kết ủy quyền
Dưới đây là các ví dụ về liên kết ủy quyền trong môi trường thực và môi trường kiểm thử sandbox để tham khảo.
Môi trường thực:
(Trung Quốc đại lục)
Môi trường kiểm thử sandbox:
(Trung Quốc đại lục)
| ⚠️ Lưu ý Timestamp dùng để tính sign chỉ có hiệu lực trong 5 phút. Sau khi timestamp và sign hết hạn, liên kết ủy quyền sẽ không còn hợp lệ và bạn cần tạo liên kết mới. |
Lấy ủy quyền từ (các) cửa hàng
Sau khi bạn chia sẻ liên kết ủy quyền với người bán, người bán cần đăng nhập vào tài khoản của họ, điền mã xác nhận được gửi đến điện thoại di động và vào trang ủy quyền.
Người bán có thể sử dụng tài khoản cửa hàng để ủy quyền một cửa hàng duy nhất hoặc tài khoản chính để ủy quyền nhiều merchant/cửa hàng. Tài khoản phụ không thể được dùng để đăng nhập vào trang ủy quyền.
| ⚠️ Lưu ý Loại ứng dụng Hệ thống nội bộ người bán chỉ có thể được ủy quyền để truy cập dữ liệu từ cửa hàng của chính người bán. Bạn cũng phải đăng nhập vào tài khoản nhà phát triển. |
Ủy quyền từ tài khoản cửa hàng
- Người bán điền thông tin đăng nhập và chọn Đăng nhập.

- Người bán điền mã xác nhận được gửi đến điện thoại di động và chọn Xác minh.

- Sau khi đăng nhập, người bán chọn Xác nhận ủy quyền.

- Sau khi ủy quyền, trang frontend sẽ chuyển hướng đến redirect URL trong liên kết ủy quyền của bạn:
https://open.shopee.com/?code=xxxxxxxxxx&shop_id=xxxxxx
Ủy quyền từ tài khoản chính
- Để đăng nhập vào tài khoản chính, người bán chọn Chuyển sang tài khoản phụ trên trang đăng nhập.

- Người bán có thể điền thông tin đăng nhập và chọn Đăng nhập.

- Người bán chọn các cửa hàng cần được ủy quyền.
Lưu ý: Đối với người bán xuyên biên giới, nếu bạn cần gọi API của merchant, hãy nhắc người bán chọn ô Auth Merchant.

Ủy quyền tài khoản chính trong nước:

- Người bán chọn Xác nhận ủy quyền để xác nhận lựa chọn của họ.

- Sau khi ủy quyền, trang frontend sẽ chuyển hướng đến redirect URL trong liên kết ủy quyền của bạn:
https://open.shopee.com/?code=xxxxxx&main_account_id=xxxxxx
Sử dụng mã ủy quyền
Sau khi người bán đã cấp ủy quyền, Open Platform sẽ trả về mã ủy quyền đến địa chỉ callback redirect URL. Bạn có thể dùng mã này để lấy access_token lần đầu tiên.
Nếu ủy quyền được thực hiện trên tài khoản cửa hàng, code và shop_id sẽ được trả về trong redirect URL.
Nếu ủy quyền được thực hiện trên tài khoản chính, code và main_account_id sẽ được trả về trong redirect URL.
| Tên tham số | Loại | Mô tả |
|---|---|---|
| code | string | Được trả về khi gọi thành công. Mã này dùng để lấy access_token và refresh_token. Chỉ có hiệu lực một lần và hết hạn sau 10 phút. |
| shop_id | int | ID của cửa hàng vừa cấp ủy quyền cho ứng dụng của bạn. Được trả về sau khi ủy quyền từ tài khoản cửa hàng. |
| main_account_id | int | ID của tài khoản chính vừa cấp ủy quyền cho cửa hàng của bạn. Được trả về sau khi ủy quyền từ tài khoản chính. |
Lấy và làm mới access_token
access_token là token động và bạn cần truyền access_token để gọi các API không công khai. Mỗi access_token có hiệu lực trong 4 giờ và có thể được sử dụng nhiều lần trong 4 giờ. Tuy nhiên, bạn cần làm mới access token bằng cách gọi RefreshAccessToken trước khi nó hết hạn để lấy access_token mới.
Refresh_token là tham số dùng để làm mới access_token. Mỗi refresh_token có hiệu lực trong 30 ngày.
⚠️ Lưu ý
access_token và refresh_token của mỗi shop_id và merchant_id cần được lưu riêng biệt.
GetAccesstoken
Sau khi ủy quyền thành công, sử dụng code và shop_id hoặc main_account_id trong redirect URL để gọi API này. Điều này giúp bạn lấy shop_id, merchant_id, access_token và refresh_token.
Đường dẫn:
Môi trường thực: https://partner.shopeemobile.com/api/v2/auth/token/get
(Trung Quốc đại lục):https://openplatform.shopee.cn/api/v2/auth/token/get
Môi trường sandbox: https://openplatform.sandbox.test-stable.shopee.sg/api/v2/auth/token/get
(Trung Quốc đại lục):https://openplatform.sandbox.test-stable.shopee.cn/api/v2/auth/token/get
Phương thức yêu cầu: POST
Tham số chung:
| Tên tham số | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
| sign | string | True | Chữ ký lấy được bằng cách băm chuỗi cơ sở (thứ tự: partner_id, api path, timestamp...) với HMAC-SHA256 sử dụng partner_key. |
| partner_id | int | True | partner_id lấy từ ứng dụng. partner_id này được đặt vào query. |
| timestamp | int | True | Timestamp, có hiệu lực trong 5 phút. |
Tham số yêu cầu:
| Tên tham số | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
| code | string | True | Mã trong redirect URL sau khi ủy quyền. Chỉ có hiệu lực một lần và hết hạn sau 10 phút. |
| partner_id | int | True | partner_id lấy từ ứng dụng. partner_id này được đặt vào request body. |
| shop_id | int | True, chỉ nhập 1. | Đối với shop_id được ủy quyền cho bạn, có thể chọn shop_id hoặc main_account_id làm tham số đầu vào. |
| main_account_id | int | Đối với main_account_id được ủy quyền cho bạn, có thể chọn shop_id hoặc main_account_id làm tham số đầu vào. |
Tham số phản hồi:
| Tên tham số | Loại | Mô tả |
|---|---|---|
| request_id | string | ID của yêu cầu API; luôn được trả về. Dùng để chẩn đoán sự cố. |
| error | string | Mã lỗi của yêu cầu API; luôn được trả về. Khi lần gọi API thành công, mã lỗi được trả về là rỗng. |
| refresh_token | string | Được trả về khi lần gọi API thành công. Dùng refresh_token để lấy access_token mới. Có hiệu lực cho mỗi shop_id và merchant_id riêng biệt, trong 30 ngày. |
| access_token | string | Được trả về khi lần gọi API thành công. Token động có thể được sử dụng nhiều lần và hết hạn sau 4 giờ. |
| expire_in | int | Được trả về khi lần gọi API thành công. Thời hạn hiệu lực của access_token, tính bằng giây. |
| message | string | Luôn được trả về. Cung cấp thông tin lỗi chi tiết. |
| merchant_id_list | int[ ] | Được trả về khi có main_account_id trong tham số đầu vào, bao gồm tất cả merchant_id được ủy quyền lần này dưới tài khoản chính. |
| shop_id_list | int[ ] | Được trả về khi có main_account_id trong tham số đầu vào, bao gồm tất cả shop_id được ủy quyền lần này dưới tài khoản chính. |
Demo code Python:
Python
print(shop_auth())
# first time request token
def get_token_shop_level(code, partner_id, tmp_partner_key, shop_id):
timest = int(time.time())
host = "https://partner.shopeemobile.com"
path = "/api/v2/auth/token/get"
body = {"code": code, "shop_id": shop_id, "partner_id": partner_id}
tmp_base_string = "%s%s%s" % (partner_id, path, timest)
base_string = tmp_base_string.encode()
partner_key = tmp_partner_key.encode()
sign = hmac.new(partner_key, base_string, hashlib.sha256).hexdigest()
url = host + path + "?partner_id=%s×tamp=%s&sign=%s" % (partner_id, timest, sign)
headers = {"Content-Type": "application/json"}
resp = requests.post(url, json=body, headers=headers)
ret = json.loads(resp.content)
access_token = ret.get("access_token")
new_refresh_token = ret.get("refresh_token")
return access_token, new_refresh_token
def get_token_account_level(code, partner_id, tmp_partner_key, main_account_id):
timest = int(time.time())
host = "https://openplatform.sandbox.test-stable.shopee.sg"
path = "/api/v2/auth/token/get"
body = {"code": code, "main_account_id": main_account_id, "partner_id": partner_id}
tmp_base_string = "%s%s%s" % (partner_id, path, timest)
base_string = tmp_base_string.encode()
partner_key = tmp_partner_key.encode()
sign = hmac.new(partner_key, base_string, hashlib.sha256).hexdigest()
url = host + path + "?partner_id=%s×tamp=%s&sign=%s" % (partner_id, timest, sign)
headers = {"Content-Type": "application/json"}
resp = requests.post(url, json=body, headers=headers)
ret = json.loads(resp.content)
access_token = ret.get("access_token")
new_refresh_token = ret.get("refresh_token")
return access_token, new_refresh_token
Demo code Java:
Java
import com.alibaba.fastjson.JSONObject;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.HashMap;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import com.alibaba.fastjson.JSON;
public class shop_auth {
public static void main(String[] args) throws ParseException, IOException {
shop_auth();
//get_token_shop_level(code,partner_id,partner_key,shop_id);
}
//generate auth url
public static void shop_auth(){
long timest = System.currentTimeMillis() / 1000L;
String host = "https://partner.shopeemobile.com";
String path = "/api/v2/shop/auth_partner";
String redirect_url = "https://www.baidu.com/";
long partner_id = 123456L;
String tmp_partner_key = "...";
String tmp_base_string = String.format("%s%s%s", partner_id, path, timest);
byte[] partner_key;
byte[] base_string;
String sign = "";
try {
base_string = tmp_base_string.getBytes("UTF-8");
partner_key = tmp_partner_key.getBytes("UTF-8");
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(partner_key, "HmacSHA256");
mac.init(secret_key);
sign = String.format("%064x",new BigInteger(1,mac.doFinal(base_string)));
} catch (Exception e) {
e.printStackTrace();
}
String url = host + path + String.format("?partner_id=%s×tamp=%s&sign=%s&redirect=%s", partner_id,timest, sign, redirect_url);
System.out.println(url);
}
//shop request for access token for the first time
public static String[] get_token_shop_level(String code,long partner_id,String tmp_partner_key,long shop_id) throws ParseException,IOException{
String[] res = new String[2];
long timest = System.currentTimeMillis() / 1000L;
String host = "https://partner.shopeemobile.com";
String path = "/api/v2/auth/token/get";
String tmp_base_string = String.format("%s%s%s", partner_id, path, timest);
byte[] partner_key;
byte[] base_string;
BigInteger sign = null;
String result = "";
try {
base_string = tmp_base_string.getBytes("UTF-8");
partner_key = tmp_partner_key.getBytes("UTF-8");
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(partner_key, "HmacSHA256");
mac.init(secret_key);
sign = new BigInteger(1,mac.doFinal(base_string));
} catch (Exception e) {
e.printStackTrace();
}
String tmp_url = host + path + String.format("?partner_id=%s×tamp=%s&sign=%s", partner_id,timest, String.format("%032x",sign));
URL url = new URL(tmp_url);
HttpURLConnection conn = null;
PrintWriter out = null;
BufferedReader in = null;
try {
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setConnectTimeout(30000);
conn.setReadTimeout(10000);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
Map<String,Object> map = new HashMap<>();
map.put("code",code);
map.put("shop_id",shop_id);
map.put("partner_id",partner_id);
String json = JSON.toJSONString(map);
conn.connect();
out = new PrintWriter(conn.getOutputStream());
out.print(json);
out.flush();
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
while((line=in.readLine())!=null){
result +=line;
}
JSONObject jsonObject = JSONObject.parseObject(result);
res[0] = (String) jsonObject.get("access_token");
res[1] = (String) jsonObject.get("refresh_token");
} catch(Exception e){
e.printStackTrace();
}finally {
try{
if(out != null){
out.close();
}
if(in != null){
in.close();
}
}catch (IOException ioe){
ioe.printStackTrace();
}
}
return res;
}
//main account request for the access token for the first time
public static String[] get_token_account_level(String code,long partner_id,String tmp_partner_key,long main_account_id) throws ParseException,IOException{
String[] res = new String[2];
long timest = System.currentTimeMillis() / 1000L;
String host = "https://openplatform.sandbox.test-stable.shopee.sg";
String path = "/api/v2/auth/token/get";
String tmp_base_string = String.format("%s%s%s", partner_id, path, timest);
byte[] partner_key;
byte[] base_string;
BigInteger sign = null;
String result = "";
try {
base_string = tmp_base_string.getBytes("UTF-8");
partner_key = tmp_partner_key.getBytes("UTF-8");
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(partner_key, "HmacSHA256");
mac.init(secret_key);
sign = new BigInteger(1,mac.doFinal(base_string));
} catch (Exception e) {
e.printStackTrace();
}
String tmp_url = host + path + String.format("?partner_id=%s×tamp=%s&sign=%s", partner_id,timest, String.format("%032x",sign));
URL url = new URL(tmp_url);
HttpURLConnection conn = null;
PrintWriter out = null;
BufferedReader in = null;
try {
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setConnectTimeout(30000);
conn.setReadTimeout(10000);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
Map<String,Object> map = new HashMap<>();
map.put("code",code);
map.put("main_account_id",main_account_id);
map.put("partner_id",partner_id);
String json = JSON.toJSONString(map);
conn.connect();
out = new PrintWriter(conn.getOutputStream());
out.print(json);
out.flush();
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
while((line=in.readLine())!=null){
result +=line;
}
JSONObject jsonObject = JSONObject.parseObject(result);
res[0] = (String) jsonObject.get("access_token");
res[1] = (String) jsonObject.get("refresh_token");
} catch(Exception e){
e.printStackTrace();
}finally {
try{
if(out != null){
out.close();
}
if(in != null){
in.close();
}
}catch (IOException ioe){
ioe.printStackTrace();
}
}
return res;
}
}
Demo code PHP:
PHP
<?php
function getTokenShopLevel($code, $partnerId, $partnerKey, $shopId) {
global $host;
$path = "/api/v2/auth/token/get";
$timest = time();
$body = array("code" => $code, "shop_id" => $shopId, "partner_id" => $partnerId);
$baseString = sprintf("%s%s%s", $partnerId, $path, $timest);
$sign = hash_hmac('sha256', $baseString, $partnerKey);
$url = sprintf("%s%s?partner_id=%s×tamp=%s&sign=%s", $host, $path, $partnerId, $timest, $sign);
$c = curl_init($url);
curl_setopt($c, CURLOPT_POST, 1);
curl_setopt($c, CURLOPT_POSTFIELDS, json_encode($body));
curl_setopt($c, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
$resp = curl_exec($c);
echo "raw result: $resp";
$ret = json_decode($resp, true);
$accessToken = $ret["access_token"];
$newRefreshToken = $ret["refresh_token"];
echo "\naccess_token: $accessToken, refresh_token: $newRefreshToken raw: $ret"."\n";
return $ret;
}
function getTokenAccountLevel($code, $partnerId, $partnerKey, $mainAccountId) {
global $host;
$path = "/api/v2/auth/token/get";
$timest = time();
$body = array("code" => $code, "main_account_id" => $mainAccountId, "partner_id" => $partnerId);
$baseString = sprintf("%s%s%s", $partnerId, $path, $timest);
$sign = hash_hmac('sha256', $baseString, $partnerKey);
$url = sprintf("%s%s?partner_id=%s×tamp=%s&sign=%s", $host, $path, $partnerId, $timest, $sign);
$c = curl_init($url);
curl_setopt($c, CURLOPT_POST, 1);
curl_setopt($c, CURLOPT_POSTFIELDS, json_encode($body));
curl_setopt($c, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($c);
echo "\nraw result ".$result."\n";
$ret = json_decode($result, true);
$accessToken = $ret["access_token"];
$newRefreshToken = $ret["refresh_token"];
echo "\naccess_token: ".$accessToken.", refresh_token: ".$newRefreshToken."\n";
return $ret;
}
$host="https://partner.shopeemobile.com";
$partnerId = 847892;
$partnerKey = "57615053704d6470644f554a78656d50484143644964436a5568777544524579";
$code="494d7a4a4f5a66524556776f66425453";
// $shopId=200520705;
// getTokenShopLevel($code, $partnerId, $partnerKey, $shopId);
$accountId=19479;
getTokenAccountLevel($code, $partnerId, $partnerKey, $accountId)
?>
RefreshAccessToken
Trước khi access_token hết hạn, làm mới bằng cách sử dụng refresh_token để gọi API này. Sau khi gọi API, một refresh_token và access_token mới sẽ được trả về đồng thời. refresh_token mới cần được sử dụng vào lần tiếp theo gọi API này.
Đường dẫn:
Môi trường thực: https://partner.shopeemobile.com/api/v2/auth/access\_token/get
(Trung Quốc đại lục): https://openplatform.shopee.cn/api/v2/auth/access\_token/get
Môi trường sandbox: https://openplatform.sandbox.test-stable.shopee.sg/api/v2/auth/access\_token/get
(Trung Quốc đại lục): https://openplatform.sandbox.test-stable.shopee.cn/api/v2/auth/access\_token/get
Phương thức yêu cầu: POST
| ⚠️ Lưu ý Mỗi main_account_id sẽ nhận được cùng một access_token và refresh_token ban đầu khi gọi GetAccessToken API lần đầu tiên. Tuy nhiên, sau khi gọi RefreshAccessToken API lần đầu tiên, một bộ access_token và refresh_token độc lập mới sẽ được tạo cho mỗi shop_id và merchant_id. Đây là ví dụ: 1. access_token và refresh_token đầu tiên lấy được từ lần gọi GetAccessToken API đầu tiên áp dụng cho 7 shop_id và 3 merchant_id. 2. Sau khi access_token đầu tiên hết hạn, bạn dùng refresh_token đầu tiên để gọi RefreshAccessToken. 3. Bạn nhận được 10 bộ access_token và refresh_token độc lập cho mỗi shop_id và merchant_id. Sau đó, shop_id và merchant_id không còn chia sẻ bất kỳ access_token hoặc refresh_token nào. |
Tham số chung:
| Tên tham số | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
| sign | string | True | Chữ ký lấy được bằng cách băm chuỗi cơ sở (thứ tự: partner_id, api path, timestamp...) với HMAC-SHA256 sử dụng partner_key. |
| partner_id | int | True | partner_id lấy từ ứng dụng. partner_id này được đặt vào query. |
| timestamp | int | True | Timestamp, có hiệu lực trong 5 phút. |
Tham số yêu cầu:
| Tên tham số | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
| refresh_token | string | True | Dùng refresh_token để lấy access_token mới. Mỗi refresh_token có hiệu lực trong 30 ngày và chỉ có thể được sử dụng một lần bởi shop_id hoặc merchant_id. |
| partner_id | int | True | partner_id lấy từ ứng dụng. partner_id này được chèn vào body. |
| shop_id | int | Có, chỉ nhập 1. | shop_id của tài khoản chính đã cấp ủy quyền cho ứng dụng của bạn. Chỉ có thể chọn shop_id hoặc merchant_id làm tham số đầu vào và chúng phải được làm mới riêng biệt. |
| merchant_id | int | merchant_id để xác định tài khoản chính đã cấp ủy quyền cho ứng dụng của bạn. Chỉ có thể chọn shop_id hoặc merchant_id làm tham số đầu vào và chúng phải được làm mới riêng biệt. |
Tham số phản hồi:
| Tên tham số | Loại | Mô tả |
|---|---|---|
| request_id | string | ID của yêu cầu API; luôn được trả về. Dùng để chẩn đoán sự cố. |
| error | string | Mã lỗi của yêu cầu API; luôn được trả về. Khi lần gọi API thành công, mã lỗi được trả về là rỗng. |
| refresh_token | string | refresh_token mới. Được trả về khi lần gọi API thành công. Dùng refresh_token để lấy access_token mới. Mỗi refresh_token có hiệu lực trong 30 ngày và chỉ có thể được sử dụng một lần bởi shop_id hoặc merchant_id. |
| access_token | string | Được trả về khi lần gọi API thành công. Mỗi access_token mới là token động có thể được sử dụng nhiều lần. Nó hết hạn sau 4 giờ. |
| expire_in | int | Được trả về khi lần gọi API thành công. Thời hạn hiệu lực của access_token, tính bằng giây. |
| message | string | Luôn được trả về. Cung cấp thông tin lỗi chi tiết. |
| merchant_id | int | Được trả về khi lần gọi API thành công. merchant_id cho lần làm mới này, để xác định từng merchant. |
| shop_id | int | Được trả về khi lần gọi API thành công. shop_id cho lần làm mới này. |
| partner_id | int | Được trả về khi lần gọi API thành công. partner_id bạn đã sử dụng cho lần làm mới này. |
| ⚠️ Lưu ý - Sau khi access_token mới được tạo, access_token cũ vẫn có hiệu lực trong 5 phút. - Ủy quyền lại sẽ kích hoạt làm mới refresh_token và access_token. - Bạn phải gọi RefreshAccessToken API trong thời hạn hiệu lực của ủy quyền. - Nếu bạn không lưu refresh_token và access_token mới được trả về, xem các giải pháp có thể. |
Demo code Python:
Python
# refresh token
def get_access_token_shop_level(shop_id, partner_id, tmp_partner_key, refresh_token):
timest = int(time.time())
host = "https://openplatform.sandbox.test-stable.shopee.sg"
path = "/api/v2/auth/access_token/get"
body = {"shop_id": shop_id, "refresh_token": refresh_token,"partner_id":partner_id}
tmp_base_string = "%s%s%s" % (partner_id, path, timest)
base_string = tmp_base_string.encode()
partner_key = tmp_partner_key.encode()
sign = hmac.new(partner_key, base_string, hashlib.sha256).hexdigest()
url = host + path + "?partner_id=%s×tamp=%s&sign=%s" % (partner_id, timest, sign)
headers = {"Content-Type": "application/json"}
resp = requests.post(url, json=body, headers=headers)
ret = json.loads(resp.content)
access_token = ret.get("access_token")
new_refresh_token = ret.get("refresh_token")
return access_token, new_refresh_token
def get_access_token_merchant_level(merchant_id, partner_id, tmp_partner_key, refresh_token):
timest = int(time.time())
host = "https://openplatform.sandbox.test-stable.shopee.sg"
path = "/api/v2/auth/access_token/get"
body = {"merchant_id": merchant_id, "refresh_token": refresh_token}
tmp_base_string = "%s%s%s" % (partner_id, path, timest)
base_string = tmp_base_string.encode()
partner_key = tmp_partner_key.encode()
sign = hmac.new(partner_key, base_string, hashlib.sha256).hexdigest()
url = host + path + "?partner_id=%s×tamp=%s&sign=%s" % (partner_id, timest, sign)
headers = {"Content-Type": "application/json"}
resp = requests.post(url, json=body, headers=headers)
ret = json.loads(resp.content)
access_token = ret.get("access_token")
new_refresh_token = ret.get("refresh_token")
return access_token, new_refresh_token
partner_id = 2006566
partner_key = "1a78dde5d6c3342f56ac939cbdd81607654c0e87725e118736ba5e3ae31c579c"
shop_id = 602226924
main_account_id = 31219
merchant_id = 45719
code = "c01204cada7b4cd0e4688154f5a256ca"
print(shop_auth())
access_token,refresh_token = get_token_account_level(code,partner_id,partner_key,main_account_id)
print(access_token)
print(refresh_token)
print(get_access_token_merchant_level(merchant_id,partner_id,partner_key,refresh_token))
Demo code Java:
Java
//shop refresh the access token
public static String[] get_access_token_shop_level(String refresh_token,long partner_id,String tmp_partner_key,long shop_id) throws ParseException,IOException{
// ... (same structure as above)
}
//merchant refresh the access token
public static String[] get_access_token_merchant_level(String refresh_token,long partner_id,String tmp_partner_key,long merchant_id) throws ParseException,IOException{
// ... (same structure as above)
}
Demo code PHP:
PHP
<?php
function getAccessTokenShopLevel($partnerId, $partnerKey, $shopId, $refreshToken) {
global $host;
$path = "/api/v2/auth/access_token/get";
$timest = time();
$body = array("partner_id" => $partnerId, "shop_id" => $shopId, "refresh_token" => $refreshToken);
$baseString = sprintf("%s%s%s", $partnerId, $path, $timest);
$sign = hash_hmac('sha256', $baseString, $partnerKey);
$url = sprintf("%s%s?partner_id=%s×tamp=%s&sign=%s", $host, $path, $partnerId, $timest, $sign);
$c = curl_init($url);
curl_setopt($c, CURLOPT_POST, 1);
curl_setopt($c, CURLOPT_POSTFIELDS, json_encode($body));
curl_setopt($c, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($c);
$ret = json_decode($result, true);
$accessToken = $ret["access_token"];
$newRefreshToken = $ret["refresh_token"];
return $ret;
}
function getAccessTokenMerchantLevel($partnerId, $partnerKey, $merchantId, $refreshToken) {
global $host;
$path = "/api/v2/auth/access_token/get";
$timest = time();
$body = array("partner_id" => $partnerId, "merchant_id" => $merchantId, "refresh_token" => $refreshToken);
$baseString = sprintf("%s%s%s", $partnerId, $path, $timest);
$sign = hash_hmac('sha256', $baseString, $partnerKey);
$url = sprintf("%s%s?partner_id=%s×tamp=%s&sign=%s", $host, $path, $partnerId, $timest, $sign);
$c = curl_init($url);
curl_setopt($c, CURLOPT_POST, 1);
curl_setopt($c, CURLOPT_POSTFIELDS, json_encode($body));
curl_setopt($c, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($c);
$ret = json_decode($result, true);
return $ret;
}
$host="https://partner.shopeemobile.com";
$partnerId = 847892;
$partnerKey = "57615053704d6470644f554a78656d50484143644964436a5568777544524579";
$merchantId=1018829;
$merchantRefreshToken="546e5064627042696756455277774f53";
getAccessTokenMerchantLevel($partnerId, $partnerKey, $merchantId, $merchantRefreshToken)
?>
Làm mới access_token và refresh_token trên tài khoản cửa hàng
- Sử dụng code và shop_id từ redirect URL để gọi GetAccessToken API và lấy cặp access_token và refresh_token đầu tiên.
Redirect URL: https://open.shopee.com/?code=7867624d4e76616648544f6e52625557&shop\_id=54804)
{"shop_id":54804,
"code":"7867624d4e76616648544f6e52625557",
"partner_id":1000016
}
- Lưu cặp access_token và refresh_token đầu tiên được trả về.
{
"refresh_token": "456e416149664b76745a6a794156794a",
"access_token": "6a55746e61546f707579627656637464",
"expire_in": 13859,
"request_id": "c040b886cfcabdfa5a23af51c595cd1b",
"error": "",
"message": ""
}
- Gọi RefreshAccessToken API để làm mới access_token và refresh_token.
{"shop_id":54804,
"refresh_token":"456e416149664b76745a6a794156794a",
"partner_id":1000016
}
- Lưu access_token và refresh_token mới.
{
"partner_id": 1000016,
"refresh_token": "666478546b6c63464867685554477a57",
"access_token": "7a5970754768697552654a466f425573",
"expire_in": 14400,
"request_id": "6d79dd0ffe4e070e185c71ca5153cd51",
"error": "",
"message": "",
"shop_id": 54804
}
Làm mới access_token và refresh_token trên tài khoản chính
- Sử dụng code và main_account_id từ URL lấy được trong quá trình ủy quyền để gọi GetAccessToken API và lấy cặp access_token và refresh_token đầu tiên.
Redirect URL: : https://open.shopee.com/?code=644d4e48787873706c5a444c776d4b59&main\_account\_id=10208
{"main_account_id":10208,
"code":"644d4e48787873706c5a444c776d4b59",
"partner_id":1000016
}
- Lưu cặp access_token và refresh_token đầu tiên được trả về.
{
"refresh_token": "684d42685667777868597a4477587455",
"access_token": "44776151594778486943647644745361",
"expire_in": 14344,
"request_id": "9199e13ee74b22411498209cb5516e24",
"merchant_id_list": [
1001705
],
"shop_id_list": [
33142,
46154
],
"error": "",
"message": ""
}
- Gọi RefreshAccessToken API để làm mới access_token và refresh_token của shop_id và merchant_id tương ứng.
{"shop_id":33142,
"refresh_token":"684d42685667777868597a4477587455",
"partner_id":1000016
}
{"merchant_id":1001705,
"refresh_token":"684d42685667777868597a4477587455",
"partner_id":1000016
}
- Lưu access_token và refresh_token mới.
{
"partner_id": 1000016,
"refresh_token": "417472546e73504949676279576c477a",
"access_token": "646d474965714a696177764963775743",
"expire_in": 14400,
"request_id": "78e64d11cb6dec6f6669282839fca916",
"error": "",
"message": "",
"shop_id": 33142
}
{
"partner_id": 1000016,
"refresh_token": "715075736d6c6570544364774f437369",
"access_token": "69634c664a7350696c6b466d5a53714a",
"expire_in": 14400,
"request_id": "51eacbc81bd6fa8fddddf1e0ef2dee16",
"error": "",
"message": "",
"merchant_id": 1001705
}