Chuyển tới nội dung chính

Ủ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ạiMô tả
signstringChữ 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_idintpartner_id lấy từ ứng dụng.
timestampintPhả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.
redirectstringURL 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&timestamp=%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&timestamp=%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&timestamp=%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&timestamp=%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:

https://partner.shopeemobile.com/api/v2/shop/auth\_partner?partner\_id=10090&redirect=https://open.shopee.com&timestamp=1594897040&sign=90c12d3932f3826f0c72242e1ec6492eec9a1298658f41f7a9469664801c4e5a

(Trung Quốc đại lục)

https://openplatform.shopee.cn/api/v2/shop/auth\_partner?partner\_id=10090&redirect=https://open.shopee.com&timestamp=1594897040&sign=90c12d3932f3826f0c72242e1ec6492eec9a1298658f41f7a9469664801c4e5a

Môi trường kiểm thử sandbox:

https://openplatform.sandbox.test-stable.shopee.sg/api/v2/shop/auth\_partner?partner\_id=1000016&redirect=https://open.shopee.com&timestamp=1657254106&sign=47e8712bb89dbc7c7f71eb690310d089b951801cb104763981de5b3dacc3f07c

(Trung Quốc đại lục)

https://openplatform.sandbox.test-stable.shopee.cn/api/v2/shop/auth\_partner?partner\_id=10090&redirect=https://open.shopee.com&timestamp=1594897040&sign=90c12d3932f3826f0c72242e1ec6492eec9a1298658f41f7a9469664801c4e5a

⚠️ 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

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

  1. 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.

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

  1. 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

  1. Để đă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.

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

  1. 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:

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

  1. 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ạiMô tả
codestringĐượ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_idintID 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_idintID 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ạiBắt buộcMô tả
signstringTrueChữ 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_idintTruepartner_id lấy từ ứng dụng. partner_id này được đặt vào query.
timestampintTrueTimestamp, có hiệu lực trong 5 phút.

Tham số yêu cầu:

Tên tham sốLoạiBắt buộcMô tả
codestringTrueMã 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_idintTruepartner_id lấy từ ứng dụng. partner_id này được đặt vào request body.
shop_idintTrue, 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_idintĐố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ạiMô tả
request_idstringID của yêu cầu API; luôn được trả về. Dùng để chẩn đoán sự cố.
errorstringMã 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_tokenstringĐượ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_tokenstringĐượ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_inintĐượ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.
messagestringLuôn được trả về. Cung cấp thông tin lỗi chi tiết.
merchant_id_listint[ ]Đượ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_listint[ ]Đượ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&timestamp=%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&timestamp=%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&timestamp=%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&timestamp=%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&timestamp=%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&timestamp=%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&timestamp=%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ạiBắt buộcMô tả
signstringTrueChữ 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_idintTruepartner_id lấy từ ứng dụng. partner_id này được đặt vào query.
timestampintTrueTimestamp, có hiệu lực trong 5 phút.

Tham số yêu cầu:

Tên tham sốLoạiBắt buộcMô tả
refresh_tokenstringTrueDù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_idintTruepartner_id lấy từ ứng dụng. partner_id này được chèn vào body.
shop_idintCó, 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_idintmerchant_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ạiMô tả
request_idstringID của yêu cầu API; luôn được trả về. Dùng để chẩn đoán sự cố.
errorstringMã 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_tokenstringrefresh_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_tokenstringĐượ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_inintĐượ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.
messagestringLuôn được trả về. Cung cấp thông tin lỗi chi tiết.
merchant_idintĐượ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_idintĐượ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_idintĐượ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&timestamp=%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&timestamp=%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&timestamp=%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&timestamp=%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

  1. 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)

Query: https://partner.shopeemobile.com/api/v2/auth/token/get?partner\_id=1000016&timestamp=1657263479&sign=9c685bc7e4a74e90f45fe1933f1d72b2d9705acda4093a9fb1ec7e2b57ccea2a

{"shop_id":54804,

"code":"7867624d4e76616648544f6e52625557",

"partner_id":1000016

}

  1. 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": ""

}

  1. Gọi RefreshAccessToken API để làm mới access_token và refresh_token.

Query: https://partner.shopeemobile.com/api/v2/auth/access\_token/get?partner\_id=1000016&timestamp=1657263479&sign=9c685bc7e4a74e90f45fe1933f1d72b2d9705acda4093a9fb1ec7e2b57ccea2a

{"shop_id":54804,

"refresh_token":"456e416149664b76745a6a794156794a",

"partner_id":1000016

}

  1. 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

  1. 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

Query: https://partner.shopeemobile.com/api/v2/auth/token/get?partner\_id=1000016&timestamp=1657263479&sign=9c685bc7e4a74e90f45fe1933f1d72b2d9705acda4093a9fb1ec7e2b57ccea2a

{"main_account_id":10208,

"code":"644d4e48787873706c5a444c776d4b59",

"partner_id":1000016

}

  1. 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": ""

}

  1. Gọi RefreshAccessToken API để làm mới access_token và refresh_token của shop_id và merchant_id tương ứng.

Query: https://partner.shopeemobile.com/api/v2/auth/access\_token/get?partner\_id=1000016&timestamp=1657868745&sign=b78833ddcf533903cfae818bbfcf2b6b630e3bc0c941dd65453632f63bf7b495

{"shop_id":33142,

"refresh_token":"684d42685667777868597a4477587455",

"partner_id":1000016

}

Query: https://partner.shopeemobile.com/api/v2/auth/access\_token/get?partner\_id=1000016&timestamp=1657868745&sign=b78833ddcf533903cfae818bbfcf2b6b630e3bc0c941dd65453632f63bf7b495

{"merchant_id":1001705,

"refresh_token":"684d42685667777868597a4477587455",

"partner_id":1000016

}

  1. 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

}