- 新增jd模块基础路由,整合app_store和payment子路由 - 实现苹果权益充值接口,支持苹果、携程及沃尔玛多个渠道 - 实现卡号密码查询接口,支持不同类别订单查询 - 新增短信认证相关接口,实现短信验证码发送及短信登录 - 新增商品管理接口,支持SKU详情查询及账号类下单功能 - 新增订单管理接口,实现订单删除功能 - 实现支付相关接口,增加刷新支付参数功能 - 定义完整请求及响应数据模型,确保接口数据规范 - 编写AppStoreSpider类,封装苹果应用内订单处理逻辑 - 引入多种代理池及请求重试机制,增强接口稳定性 - 添加详细日志记录,便于请求追踪与错误排查
818 lines
37 KiB
Python
818 lines
37 KiB
Python
import hashlib
|
||
import json
|
||
from logging import LoggerAdapter
|
||
import platform
|
||
import re
|
||
import time
|
||
|
||
import fake_useragent
|
||
from curl_cffi import ProxySpec, requests
|
||
|
||
from apps.jd.schemas.models import QueryCardResponseData
|
||
from apps.shared.proxy_pool.proxy_pool import ProxyPoolFactory
|
||
from core.config import ProxyPoolType
|
||
from core.exceptions import JDServiceException
|
||
from core.responses import BusinessCode
|
||
from observability.logging import get_logger_with_trace
|
||
|
||
logger: LoggerAdapter = get_logger_with_trace(__name__)
|
||
|
||
|
||
class XiechengCardSpider:
|
||
"""
|
||
携程
|
||
100元:10140177420168
|
||
200元:10148161391225
|
||
300元:10148163028307
|
||
500元:10148178960836
|
||
1000元:10148179392280
|
||
"""
|
||
|
||
def __init__(self, cookies, order_num, sku_id):
|
||
self.eid = None
|
||
self.x_token = None
|
||
self._session = requests.Session()
|
||
self._order_num = order_num
|
||
self.cookies = cookies
|
||
self.time_stamp = int(time.time() * 1000)
|
||
self.current_os = platform.system()
|
||
self.sku_id = sku_id
|
||
self.submit_order_url = "https://api.m.jd.com/appstore/submitorder"
|
||
self.ticket_url = "https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkcaptcha"
|
||
self.jd_api = "https://api.m.jd.com/api"
|
||
self.action_url = "https://api.m.jd.com/client.action"
|
||
self.check_captcha_url = (
|
||
"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkcaptcha"
|
||
)
|
||
self._expiring_pool = ProxyPoolFactory.get_proxy_pool(
|
||
ProxyPoolType.EXPIRING, expire_time=60
|
||
)
|
||
self.user_agent = fake_useragent.FakeUserAgent().chrome
|
||
|
||
def _get_proxy(self):
|
||
proxy = self._expiring_pool.get_proxy(order_id=self._order_num)
|
||
return ProxySpec(all=proxy) if proxy else None
|
||
|
||
# def get_ticket_res(self):
|
||
# for i in range(1):
|
||
# try:
|
||
# headers = {
|
||
# "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
||
# "Accept-Language": "zh-CN,zh;q=0.9",
|
||
# "Cache-Control": "no-cache",
|
||
# "Connection": "keep-alive",
|
||
# "Pragma": "no-cache",
|
||
# "Upgrade-Insecure-Requests": "1",
|
||
# "User-Agent": self.user_agent,
|
||
# }
|
||
# url = f"http://119.23.175.61:8877/captcha/tx?aid=2093769752&ip={self.proxy}&host=https://t.captcha.qq.com"
|
||
# logger.info(f"获取ticket请求代理:{self.proxy}")
|
||
# logger.info(f"获取ticket请求:{url}")
|
||
# response = self._session.get(
|
||
# url, headers=headers, verify=False, timeout=60
|
||
# )
|
||
# logger.info(f"获取ticket结果:{response.text}")
|
||
# if response.json().get("msg_code") != 200:
|
||
# continue
|
||
# if response.json().get("result", {}).get(
|
||
# "ticket"
|
||
# ) and response.json().get("result", {}).get("randstr"):
|
||
# return {
|
||
# "ticket": response.json().get("result", {}).get("ticket"),
|
||
# "randstr": response.json().get("result", {}).get("randstr"),
|
||
# }
|
||
# except Exception as e:
|
||
# logger.error(e)
|
||
# raise Exception("获取ticket失败")
|
||
|
||
def get_pay_res(self, order_id):
|
||
headers = {
|
||
"accept": "*/*",
|
||
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
|
||
"content-type": "application/json;charset=UTF-8",
|
||
"origin": "https://trade.m.jd.com",
|
||
"priority": "u=1, i",
|
||
"referer": "https://trade.m.jd.com/",
|
||
"sec-ch-ua": '"Chromium";v="130", "Microsoft Edge";v="130", "Not?A_Brand";v="99"',
|
||
"sec-ch-ua-mobile": "?0",
|
||
"sec-ch-ua-platform": '"Windows"',
|
||
"sec-fetch-dest": "empty",
|
||
"sec-fetch-mode": "cors",
|
||
"sec-fetch-site": "same-site",
|
||
"user-agent": self.user_agent,
|
||
"x-referer-page": "https://trade.m.jd.com/order/orderlist_jdm.shtml",
|
||
"x-rp-client": "h5_1.0.0",
|
||
"cookie": self.cookies,
|
||
}
|
||
body = (
|
||
'{"appType":3,"bizType":"2","deviceUUId":"","platform":3,"sceneval":"2","source":"m_inner_myJd.orderFloor_orderlist","systemBaseInfo":"{\\"pixelRatio\\":1.25,\\"screenWidth\\":2048,\\"screenHeight\\":1152,\\"windowWidth\\":414,\\"windowHeight\\":1034,\\"statusBarHeight\\":null,\\"safeArea\\":{\\"bottom\\":0,\\"height\\":0,\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"width\\":0},\\"bluetoothEnabled\\":false,\\"locationEnabled\\":false,\\"wifiEnabled\\":false,\\"deviceOrientation\\":\\"landscape\\",\\"benchmarkLevel\\":-1,\\"brand\\":\\"\\",\\"model\\":\\"\\",\\"system\\":null,\\"platform\\":\\"Win32\\",\\"SDKVersion\\":\\"\\",\\"enableDebug\\":false,\\"language\\":\\"zh-CN\\",\\"version\\":\\"\\",\\"theme\\":\\"light\\",\\"fontSizeSetting\\":null,\\"albumAuthorized\\":false,\\"cameraAuthorized\\":false,\\"locationAuthorized\\":false,\\"microphoneAuthorized\\":false,\\"notificationAuthorized\\":false,\\"notificationAlertAuthorized\\":false,\\"notificationBadgeAuthorized\\":false,\\"notificationSoundAuthorized\\":false,\\"phoneCalendarAuthorized\\":false,\\"locationReducedAccuracy\\":false,\\"environment\\":\\"\\"}","orderId":"%s","origin":10,"tenantCode":"jgm","bizModelCode":"2","bizModeClientType":"M","bizModeFramework":"Taro","externalLoginType":1,"token":"3852b12f8c4d869b7ed3e2b3c68c9436","appId":"m91d27dbf599dff74"}'
|
||
% order_id
|
||
)
|
||
encrypt_body = self.sha256_hash(body)
|
||
timestamp = f"{int(time.time() * 1000)}"
|
||
object_id = "9b070"
|
||
function_id = "pay_info_m"
|
||
h5st = self.get_h5st(timestamp, encrypt_body, object_id, function_id)
|
||
|
||
params = {
|
||
"t": f"{self.time_stamp}",
|
||
"loginType": "2",
|
||
"loginWQBiz": "golden-trade",
|
||
"appid": "m_core",
|
||
"client": "Win32",
|
||
"clientVersion": "",
|
||
"build": "",
|
||
"osVersion": "null",
|
||
"screen": "2048*1152",
|
||
"networkType": "4g",
|
||
"partner": "",
|
||
"forcebot": "",
|
||
"d_brand": "",
|
||
"d_model": "",
|
||
"lang": "zh-CN",
|
||
"scope": "",
|
||
"sdkVersion": "",
|
||
"openudid": "",
|
||
"uuid": "17295878824571442265187",
|
||
"x-api-eid-token": self.x_token,
|
||
"functionId": "pay_info_m",
|
||
"body": body,
|
||
"h5st": h5st,
|
||
}
|
||
proxy = self._get_proxy()
|
||
response = self._session.get(
|
||
self.action_url,
|
||
headers=headers,
|
||
params=params,
|
||
verify=False,
|
||
proxies=proxy,
|
||
)
|
||
return response.json()
|
||
|
||
def plat_pay_channel_res(self, pay_id):
|
||
headers = {
|
||
"accept": "application/json, text/plain, */*",
|
||
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
|
||
"content-type": "application/x-www-form-urlencoded",
|
||
"origin": "https://mpay.m.jd.com",
|
||
"priority": "u=1, i",
|
||
"referer": "https://mpay.m.jd.com/",
|
||
"sec-ch-ua": '"Chromium";v="130", "Microsoft Edge";v="130", "Not?A_Brand";v="99"',
|
||
"sec-ch-ua-mobile": "?0",
|
||
"sec-ch-ua-platform": '"Windows"',
|
||
"sec-fetch-dest": "empty",
|
||
"sec-fetch-mode": "cors",
|
||
"sec-fetch-site": "same-site",
|
||
"user-agent": self.user_agent,
|
||
"x-referer-page": "https://mpay.m.jd.com/mpay.623f9498223cf9b9de9f.html",
|
||
"x-rp-client": "h5_1.0.0",
|
||
"cookie": self.cookies,
|
||
}
|
||
params = {"functionId": "platPayChannel", "appid": "mcashier", "scval": "mpay"}
|
||
body = (
|
||
'{"appId":"m_D1vmUq63","payId":"%s","source":"mcashier","origin":"h5","mcashierTraceId":1729842386189}'
|
||
% pay_id
|
||
)
|
||
encrypt_body = self.sha256_hash(body)
|
||
timestamp = f"{int(time.time() * 1000)}"
|
||
object_id = "303a7"
|
||
function_id = "plat_pay_channel"
|
||
proxy = self._get_proxy()
|
||
h5st = self.get_h5st(timestamp, encrypt_body, object_id, function_id)
|
||
data = {"body": body, "x-api-eid-token": self.x_token, "h5st": h5st}
|
||
response = self._session.post(
|
||
self.action_url,
|
||
headers=headers,
|
||
params=params,
|
||
data=data,
|
||
verify=False,
|
||
proxies=proxy,
|
||
)
|
||
return response.json()
|
||
|
||
def get_locdetails(self, order_id):
|
||
url = "https://api.m.jd.com/"
|
||
data = {
|
||
"appid": "loc",
|
||
"loginType": "2",
|
||
"cthr": "1",
|
||
"loginWQBiz": "locdetails",
|
||
"t": f"{int(time.time() * 1000)}",
|
||
"functionId": "queryLocOrderDetail",
|
||
"body": '{"version":"1.0.0","source":"","requestId":1757908327795,"orderId":"%s","oldHttp2Color":true}'
|
||
% order_id,
|
||
}
|
||
headers = {
|
||
"accept": "application/json, text/plain, */*",
|
||
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
|
||
"cache-control": "no-cache",
|
||
"content-type": "application/x-www-form-urlencoded",
|
||
"origin": "https://locdetails.jd.com",
|
||
"pragma": "no-cache",
|
||
"priority": "u=1, i",
|
||
"referer": "https://locdetails.jd.com/",
|
||
"sec-fetch-dest": "empty",
|
||
"sec-fetch-mode": "cors",
|
||
"sec-fetch-site": "same-site",
|
||
"user-agent": self.user_agent,
|
||
"x-referer-page": "https://locdetails.jd.com/h5/index.html",
|
||
"x-rp-client": "h5_1.0.0",
|
||
"cookie": self.cookies,
|
||
}
|
||
# proxy = self._get_proxy()
|
||
response = self._session.post(
|
||
url,
|
||
headers=headers,
|
||
data=data,
|
||
verify=False,
|
||
# proxies={
|
||
# "http": proxy,
|
||
# "https": proxy,
|
||
# },
|
||
)
|
||
res = response.json()
|
||
if res.get("code") == 20001:
|
||
return BusinessCode.JD_ORDER_CK_ERR, QueryCardResponseData(
|
||
order_status="",
|
||
card_num="",
|
||
card_pwd="",
|
||
remark=str(res),
|
||
)
|
||
|
||
if res and res.get("code") == 0:
|
||
logger.info(f"请求结果 {response.json()}")
|
||
data = res.get("data", {})
|
||
order_status_data = data.get("orderStatusData", {})
|
||
shop_sku_info_list = data.get("shopSkuInfoList", [])
|
||
|
||
card_num = ""
|
||
card_pwd = ""
|
||
|
||
if shop_sku_info_list and len(shop_sku_info_list) > 0:
|
||
sku_infos = shop_sku_info_list[0].get("skuInfos", [])
|
||
if sku_infos and len(sku_infos) > 0:
|
||
code_info = sku_infos[0].get("codeInfo", [])
|
||
if code_info and len(code_info) > 0:
|
||
card_num = code_info[0].get("cardNum", "")
|
||
card_pwd = code_info[0].get("pwdNum", "")
|
||
|
||
return BusinessCode.SUCCESS, QueryCardResponseData(
|
||
order_status=order_status_data.get("statusName", ""),
|
||
card_num=card_num,
|
||
card_pwd=card_pwd,
|
||
)
|
||
else:
|
||
return BusinessCode.JD_ORDER_NORMAL_ERR, QueryCardResponseData(
|
||
order_status="", card_num="", card_pwd="", remark=str(res)
|
||
)
|
||
|
||
def plat_wx_pay_res(self, pay_id):
|
||
headers = {
|
||
"accept": "application/json, text/plain, */*",
|
||
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
|
||
"content-type": "application/x-www-form-urlencoded",
|
||
"origin": "https://mpay.m.jd.com",
|
||
"priority": "u=1, i",
|
||
"referer": "https://mpay.m.jd.com/",
|
||
"sec-ch-ua": '"Chromium";v="130", "Microsoft Edge";v="130", "Not?A_Brand";v="99"',
|
||
"sec-ch-ua-mobile": "?0",
|
||
"sec-ch-ua-platform": '"Windows"',
|
||
"sec-fetch-dest": "empty",
|
||
"sec-fetch-mode": "cors",
|
||
"sec-fetch-site": "same-site",
|
||
"user-agent": self.user_agent,
|
||
"x-referer-page": "https://mpay.m.jd.com/mpay.623f9498223cf9b9de9f.html",
|
||
"x-rp-client": "h5_1.0.0",
|
||
"cookie": self.cookies,
|
||
}
|
||
params = {"functionId": "platWapWXPay", "appid": "mcashier", "scval": "mpay"}
|
||
body = (
|
||
'{"appId":"m_D1vmUq63","payId":"%s","eid":"%s","source":"mcashier","origin":"h5","mcashierTraceId":1729837716957}'
|
||
% (pay_id, self.eid)
|
||
)
|
||
encrypt_body = self.sha256_hash(body)
|
||
timestamp = f"{int(time.time() * 1000)}"
|
||
object_id = "303a7"
|
||
function_id = "plat_wx_pay"
|
||
h5st = self.get_h5st(timestamp, encrypt_body, object_id, function_id)
|
||
data = {"body": body, "x-api-eid-token": self.x_token, "h5st": h5st}
|
||
proxy = self._get_proxy()
|
||
response = self._session.post(
|
||
self.action_url,
|
||
headers=headers,
|
||
params=params,
|
||
data=data,
|
||
verify=False,
|
||
proxies=proxy,
|
||
)
|
||
return response.json()
|
||
|
||
# def get_deep_link_res(self, mweb_url):
|
||
# headers = {
|
||
# "Host": "wx.tenpay.com",
|
||
# "sec-ch-ua-platform": '"Windows"',
|
||
# "User-Agent": self.user_agent,
|
||
# "sec-ch-ua": '"Chromium";v="130", "Microsoft Edge";v="130", "Not?A_Brand";v="99"',
|
||
# "sec-ch-ua-mobile": "?0",
|
||
# "Accept": "*/*",
|
||
# "Sec-Fetch-Site": "same-origin",
|
||
# "Sec-Fetch-Mode": "cors",
|
||
# "Sec-Fetch-Dest": "empty",
|
||
# "Referer": mweb_url,
|
||
# "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
|
||
# }
|
||
# prepay_id = re.search(r"prepay_id=(wx\w+)", mweb_url).group(1)
|
||
# package = re.search(r"package=(\d+)", mweb_url).group(1)
|
||
# ticket_res = self.get_ticket_res()
|
||
# logger.info(f"订单号:{self._order_num},获取ticket返回:{ticket_res}")
|
||
# ticket = ticket_res["ticket"]
|
||
# randstr = ticket_res["randstr"]
|
||
# params = {
|
||
# "ticket": ticket,
|
||
# "randstr": randstr,
|
||
# "prepayid": prepay_id,
|
||
# "package": package,
|
||
# }
|
||
# proxy = self._get_proxy()
|
||
# response = self._session.get(
|
||
# self.check_captcha_url,
|
||
# headers=headers,
|
||
# params=params,
|
||
# verify=False,
|
||
# proxies=proxy,
|
||
# )
|
||
# return response.json()
|
||
|
||
@staticmethod
|
||
def sha256_hash(text):
|
||
# 创建 SHA-256 哈希对象
|
||
sha256 = hashlib.sha256()
|
||
# 更新哈希对象(输入必须为字节类型)
|
||
sha256.update(text.encode("utf-8"))
|
||
# 返回 16 进制格式的哈希值
|
||
return sha256.hexdigest()
|
||
|
||
def _get_pt_pin(self, cookie_str):
|
||
cookies = {}
|
||
for item in cookie_str.strip(";").split(";"):
|
||
if "=" in item:
|
||
key, value = item.strip().split("=", 1)
|
||
cookies[key] = value
|
||
|
||
pt_pin = cookies.get("pt_pin")
|
||
return pt_pin
|
||
|
||
def get_h5st(self, timestamp, body, object_id, function_id):
|
||
sua = "Windows NT 10.0; Win64; x64"
|
||
pt_pin = self._get_pt_pin(self.cookies)
|
||
params_str = f"ai={object_id}&sua={sua}&pin={pt_pin}&appid=m_core&functionId={function_id}&body={body}&client=Win32&clientVersion=2.5.2&t={timestamp}"
|
||
h5st = requests.get(f"http://127.0.0.1:8887/jd/h5st?{params_str}").text
|
||
return h5st
|
||
|
||
def get_x_token(self):
|
||
proxy = None
|
||
_proxy = self._get_proxy()
|
||
if _proxy:
|
||
proxy = _proxy.get("all")
|
||
|
||
data = {"type": "1", "str": self.user_agent}
|
||
if proxy:
|
||
data["proxy"] = proxy
|
||
|
||
response = requests.post(
|
||
"http://127.0.0.1:8887/api/stash/algorithm",
|
||
data=data,
|
||
)
|
||
logger.info(f"获取x-api-eid-token返回:{response.text}")
|
||
res = response.json()
|
||
token = res["data"]["token"]
|
||
eid = res["data"]["eid"]
|
||
return token, eid
|
||
|
||
def get_current_order(self, retry_count: int = 3):
|
||
if not retry_count:
|
||
return JDServiceException(BusinessCode.JD_ORDER_RISK_ERR)
|
||
body = (
|
||
'{"deviceUUID":"6785593751540242498","appId":"wxae3e8056daea8727","appVersion":"2.5.2","tenantCode":"jgm","bizModelCode":"3","bizModeClientType":"M","token":"3852b12f8c4d869b7ed3e2b3c68c9436","externalLoginType":1,"referer":"https://item.m.jd.com/","resetGsd":true,"useBestCoupon":"1","locationId":"1-72-2819-0","packageStyle":true,"sceneval":"2","balanceCommonOrderForm":{"supportTransport":false,"action":1,"overseaMerge":false,"international":false,"netBuySourceType":0,"appVersion":"2.5.2","tradeShort":false},"balanceDeviceInfo":{"resolution":"2048*1152"},"cartParam":{"skuItem":{"skuId":"%s","num":"1","orderCashBack":false,"extFlag":{}}}}'
|
||
% self.sku_id
|
||
)
|
||
encrypt_body = self.sha256_hash(body)
|
||
timestamp = f"{int(time.time() * 1000)}"
|
||
object_id = "bd265"
|
||
function_id = "balance_getCurrentOrder_m"
|
||
h5st = self.get_h5st(timestamp, encrypt_body, object_id, function_id)
|
||
headers = {
|
||
"accept": "*/*",
|
||
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
|
||
"cache-control": "no-cache",
|
||
"content-type": "application/x-www-form-urlencoded",
|
||
"origin": "https://trade.m.jd.com",
|
||
"pragma": "no-cache",
|
||
"priority": "u=1, i",
|
||
"referer": "https://trade.m.jd.com/",
|
||
"sec-ch-ua": '"Chromium";v="140", "Not=A?Brand";v="24", "Microsoft Edge";v="140"',
|
||
"sec-ch-ua-mobile": "?0",
|
||
"sec-ch-ua-platform": '"Windows"',
|
||
"sec-fetch-dest": "empty",
|
||
"sec-fetch-mode": "cors",
|
||
"sec-fetch-site": "same-site",
|
||
"user-agent": self.user_agent,
|
||
"x-referer-page": "https://trade.m.jd.com/pay",
|
||
"x-rp-client": "h5_1.0.0",
|
||
"cookie": self.cookies,
|
||
}
|
||
|
||
url = "https://api.m.jd.com/client.action"
|
||
data = {
|
||
"t": timestamp,
|
||
"body": body,
|
||
"h5st": h5st,
|
||
"scval": self.sku_id,
|
||
"client": "Win32",
|
||
"clientVersion": "2.5.2",
|
||
"osVersion": "other",
|
||
"screen": "2048*1152",
|
||
"networkType": "false",
|
||
"d_brand": "",
|
||
"d_model": "",
|
||
"lang": "zh-CN",
|
||
"sdkVersion": "2.5.2",
|
||
"appid": "m_core",
|
||
"openudid": "",
|
||
"x-api-eid-token": self.x_token,
|
||
"functionId": "balance_getCurrentOrder_m",
|
||
"uuid": "17573259367521124301157",
|
||
"loginType": "2",
|
||
"xAPIScval3": "unknown",
|
||
}
|
||
proxy = self._get_proxy()
|
||
response = self._session.post(
|
||
url,
|
||
headers=headers,
|
||
data=data,
|
||
impersonate="chrome",
|
||
verify=False,
|
||
proxies=proxy,
|
||
)
|
||
if (
|
||
response.ok
|
||
and response.json()
|
||
and response.json().get("body", {}).get("errorCode") == "601"
|
||
):
|
||
return self.get_current_order(retry_count - 1)
|
||
|
||
def submit_order(self):
|
||
body = {
|
||
"deviceUUID": "6279258698405299736",
|
||
"appId": "wxae3e8056daea8727",
|
||
"tenantCode": "jgm",
|
||
"bizModelCode": "3",
|
||
"bizModeClientType": "M",
|
||
"token": "3852b12f8c4d869b7ed3e2b3c68c9436",
|
||
"externalLoginType": 1,
|
||
"appVersion": "2.5.2",
|
||
"referer": "https://item.m.jd.com/",
|
||
"checkPayPassport": False,
|
||
"checkpwdV2": False,
|
||
"isEncryptionMobile": True,
|
||
"outStockVendorIdList": [12514479],
|
||
"mainSkuIdList": [int(self.sku_id)],
|
||
"balanceDataServerSkuVOList": [
|
||
{
|
||
"id": int(self.sku_id),
|
||
"jdPrice": "499.00",
|
||
"buyNum": 1,
|
||
"firstCategoryId": 4938,
|
||
"secondCategoryId": 11760,
|
||
"thirdCategoryId": 22501,
|
||
"promoId": 305236894242,
|
||
"venderId": 12514479,
|
||
"type": 1,
|
||
}
|
||
],
|
||
"balanceTableWareVoList": [{}],
|
||
"cashierDeskBackUrl": f"https://trade.m.jd.com/buy/done.shtml?dealId=%24%7BorderId%7D&sceneval=2&fromPay=1&ptag=7039.27.14&gift_skuid={self.sku_id}&gift_venderid=12514479&gift_cid=22501&normal=1",
|
||
"payType": "4",
|
||
"subPayType": "",
|
||
"licenseList": [],
|
||
"balanceCommonOrderForm": {
|
||
"action": 1,
|
||
"overseaMerge": False,
|
||
"international": False,
|
||
"netBuySourceType": 0,
|
||
"appVersion": "2.5.2",
|
||
"supportTransport": False,
|
||
"tradeShort": False,
|
||
"useChannelFlag": "10000000",
|
||
"hasSingleOrderGovSubsidy": False,
|
||
"unionPayCouponEffective": False,
|
||
"oldAgeStyle": False,
|
||
"balanceRefreshByAction": "1",
|
||
"supportUserPrivacy": True,
|
||
"userPrivacyChecked": True,
|
||
},
|
||
"balanceExt": {
|
||
"baiDuJumpButtonSwitch": False,
|
||
"bubbleTips": {"enable": True, "num": 1, "time": 3, "useNum": 0},
|
||
"cashierDeskEnable": True,
|
||
"cashierPayFlag": "0",
|
||
"checkIdInfo": False,
|
||
"couponRedText": "",
|
||
"hasBackupStorage": False,
|
||
"hasCwbg": False,
|
||
"hasFreightInsurance": False,
|
||
"isInternational": False,
|
||
"isSupportTranport": False,
|
||
"jdCombineType": 0,
|
||
"knowledgeServiceStatus": 0,
|
||
"noAddressMatchDegradeSwitch": True,
|
||
"overseaMerge": False,
|
||
"plusFloorStr": '{"addressType":0,"area":"19-1601-3633-63243","freightInfoList":[],"invoiceType":1,"payWay":4,"plusPromotionRequest":{"couponTotalAmount":0.00,"fareCouponTotalAmount":0.00,"officialDiscountTotalDiscount":0.00,"promotionReduceTotalAmount":0.00,"promotionTotalPrice":499.00,"redBagTotalAmount":0.00,"totalCashGiftDiscount":0,"totalCashGiftNew":0,"totalCashGiftOld":0,"totalParallelDiscount":0.00},"plusStatus":"203","requestConditionList":[105,106,305,529,523,521,522,351],"skuInfoRequestList":[{"col_type":"0","companyType":0,"factoryShip":0,"firstCategory":4938,"isCanUseDongCoupon":1,"isCanUseJingCoupon":1,"isJxzy":0,"isLoc":1,"isOverseaPurchase":0,"jdPrice":"499.00","number":"1","secondCategory":11760,"shopId":12204479,"skuExtension":{"fields":{"fare":"2849262","saler":"","saleAttributes":"[{\\"saleName\\":\\"颜色\\",\\"dim\\":1},{\\"saleName\\":\\"尺码\\",\\"dim\\":2}]","maxBuyNum":"19","is7ToReturn":"0","features":"consumptionVAT:0,inputVAT:0,outputVAT:0","vender_attribute":"","isHitGovSubsidy":"0","selectedGBCZGovConsumerCoupon":"false","yn":"1","vender_name":"易点生活电子商务有限公司","product_id":"10028314345641","sale_atts":"","warranty":"","timeliness_id":"0","sku_name":"【谨防刷单诈骗】沃尔玛大卖场卡500元 官方卡密 卡号8688 不支持山姆 本店不刷单 谨防诈骗 不支持退换","supply_unit":"","model":"","shopId":"12204479","cn_sku_name":"【谨防刷单诈骗】沃尔玛大卖场卡500元 官方卡密 卡号8688 不支持山姆 本店不刷单 谨防诈骗 不支持退换","height":"0","MN":"19","first_buyer_post":"4541","unLimit_cid":"22501","isCanVAT":"0","pay_first":"1","tsfw":"p8,","ms":"0","weight":"0","sku_id":"%s","tax":"consumptionVAT:0,inputVAT:0,outputVAT:0","shop_name":"沃尔玛礼品卡专卖店","product_name":"【谨防刷单诈骗】沃尔玛大卖场卡500元 官方卡密 卡号8688 不支持山姆","brand_id":"250870","shop_id":"12204479","size":"不支持退换","brandId":"250870","col_type":"0","color":"本店不刷单 谨防诈骗","cn_color":"本店不刷单 谨防诈骗","isLOC":"2","img_dfs_url":"jfs/t1/225028/24/16896/94540/6667fb55Fad484540/4069fd317318e9da.jpg","outer_id":"DSwemmck0500","platform":"1","vender_id":"12514479","jc_buyer":"","category_id":"22501","fxg":"0","isQdh":"0","venderAttribute":"","sku_tag":"0","category_id1":"4938","sku_mark":"0","template_type_attributes":"[{\\"attrid\\":\\"1001050620\\",\\"dim\\":1,\\"saleName\\":\\"颜色\\",\\"saleValue\\":\\"本店不刷单 谨防诈骗\\",\\"sequenceNo\\":1,\\"valueId\\":\\"2916524754\\"},{\\"attrid\\":\\"1001051741\\",\\"dim\\":2,\\"saleName\\":\\"尺码\\",\\"saleValue\\":\\"不支持退换\\",\\"sequenceNo\\":1,\\"valueId\\":\\"3924738280\\"}]","category_id2":"11760","sale_template_id":"POP_MODEL","jc_saler":"","day_limited_sales":"19","length":"0","locGroupId":"-100","vender_col_type":"0","sku_status":"1","allnum":"0","containsGovConsumerCoupon":"false","width":"0"},"fresh":false,"num":1,"parallelPromo":false,"samShop":false,"selfSupport":false,"shoppingMalls":false,"skuPriceAfterSinglePromotion":"499.00","skuUuid":"1012_F2t2t3H1499005262095200256","spuId":"-1","storeId":"-1","vendor":"12514479","vendorType":2},"skuId":%s,"skuMark":"","spuId":"-1","thirdCategory":22501,"uuid":"1012_F2t2t3H1499005262095200256","venderId":12514479,"vender_bizid":",popsop,","vender_col_type":"0","vendorType":0}],"totalPrice":"499.00"}'
|
||
% (self.sku_id, self.sku_id),
|
||
"selectedCouponNum": 0,
|
||
"sellLargeDay": "7",
|
||
"supportPaymentSkuList": [self.sku_id],
|
||
"useBestCoupon": True,
|
||
},
|
||
"actualPayment": "499.00",
|
||
"sendGift": {},
|
||
"dsList": [
|
||
{"paramName": "report_time", "paramVal": ""},
|
||
{"paramName": "deal_id", "paramVal": ""},
|
||
{"paramName": "buyer_uin"},
|
||
{"paramName": "pin", "paramVal": ""},
|
||
{
|
||
"paramName": "cookie_pprd_p",
|
||
"paramVal": "UUID.17512753463451844059233-LOGID.1751857899901.1014192400",
|
||
},
|
||
{
|
||
"paramName": "cookie_pprd_s",
|
||
"paramVal": "76161171.17512753463451844059233.1751275346.1751856681.1751857862.11",
|
||
},
|
||
{"paramName": "cookie_pprd_t"},
|
||
{"paramName": "ip", "paramVal": ""},
|
||
{"paramName": "visitkey", "paramVal": "6279258698405299736"},
|
||
{"paramName": "gen_entrance", "paramVal": ""},
|
||
{"paramName": "deal_src", "paramVal": "7"},
|
||
{"paramName": "item_type", "paramVal": "1"},
|
||
{"paramName": "fav_unixtime", "paramVal": ""},
|
||
{"paramName": "pay_type", "paramVal": "0"},
|
||
{"paramName": "ab_test", "paramVal": ""},
|
||
{"paramName": "serilize_type", "paramVal": "0"},
|
||
{"paramName": "property1", "paramVal": "0"},
|
||
{"paramName": "property2", "paramVal": "0"},
|
||
{"paramName": "property3", "paramVal": "0"},
|
||
{"paramName": "property4", "paramVal": "0"},
|
||
{"paramName": "seller_uin", "paramVal": "0"},
|
||
{"paramName": "pp_item_id", "paramVal": ""},
|
||
{"paramName": "openid"},
|
||
{"paramName": "orderprice", "paramVal": ""},
|
||
{"paramName": "actiontype", "paramVal": ""},
|
||
{"paramName": "extinfo", "paramVal": ""},
|
||
{"paramName": "ext1", "paramVal": self.sku_id},
|
||
{"paramName": "ext2", "paramVal": ""},
|
||
{"paramName": "ext3", "paramVal": ""},
|
||
{"paramName": "ext4", "paramVal": ""},
|
||
{"paramName": "ext5", "paramVal": ""},
|
||
{"paramName": "ext6"},
|
||
{"paramName": "ext7", "paramVal": ""},
|
||
{"paramName": "ext8", "paramVal": "0"},
|
||
{"paramName": "ext9", "paramVal": "0|0|0|0|0||0|0"},
|
||
{"paramName": "ext10", "paramVal": "|||"},
|
||
{
|
||
"paramName": "ext11",
|
||
"paramVal": "http://wq.jd.com/wxapp/pages/pay/index/index",
|
||
},
|
||
{"paramName": "ext12", "paramVal": "1"},
|
||
{"paramName": "ext13", "paramVal": ""},
|
||
{"paramName": "ext14", "paramVal": ""},
|
||
{"paramName": "ext15", "paramVal": ""},
|
||
{"paramName": "ext16", "paramVal": ""},
|
||
{
|
||
"paramName": "ext17",
|
||
"paramVal": "76161171%7Ciosapp%7Ct_335139774%7Cappshare%7CCopyURL_shareidde4fa5e467a1fbe323b52ed0fa61777f5ce3e1fe17503293501852_shangxiang_none%7C1751857899902",
|
||
},
|
||
{"paramName": "ext18"},
|
||
{"paramName": "ext19", "paramVal": ""},
|
||
{"paramName": "ext20"},
|
||
{
|
||
"paramName": "fpa",
|
||
"paramVal": "7f07f4e1-6ac2-2918-ff9a-18320538d8b2-1743129927",
|
||
},
|
||
{
|
||
"paramName": "fpb",
|
||
"paramVal": "BApXSBoHW4fJA8VrxmIXHrE1TcUW-_mloBgFTnghK9xJ1MvE2-4G2",
|
||
},
|
||
{"paramName": "ext21", "paramVal": ""},
|
||
{"paramName": "ext22", "paramVal": ""},
|
||
{"paramName": "ext23", "paramVal": "NULL"},
|
||
{"paramName": "ext24", "paramVal": "NULL"},
|
||
{"paramName": "ext25", "paramVal": "NULL"},
|
||
{"paramName": "ext26", "paramVal": "NULL"},
|
||
{"paramName": "ext27", "paramVal": "NULL"},
|
||
{"paramName": "ext28", "paramVal": "NULL"},
|
||
{"paramName": "ext29", "paramVal": "NULL"},
|
||
{"paramName": "ext30", "paramVal": "NULL"},
|
||
{"paramName": "ext31", "paramVal": "NULL"},
|
||
{"paramName": "ext32", "paramVal": "NULL"},
|
||
{"paramName": "ext33", "paramVal": "NULL"},
|
||
{"paramName": "ext34", "paramVal": "NULL"},
|
||
{"paramName": "ext35", "paramVal": "NULL"},
|
||
{"paramName": "ext36", "paramVal": "NULL"},
|
||
{"paramName": "ext37", "paramVal": "NULL"},
|
||
{"paramName": "ext38", "paramVal": "NULL"},
|
||
{"paramName": "dt", "paramVal": ""},
|
||
],
|
||
"govUseGisLocation": False,
|
||
"packageStyle": True,
|
||
"sceneval": "2",
|
||
"balanceDeviceInfo": {"resolution": "2048*1152"},
|
||
"balanceId": "5351641558031892481751857904612",
|
||
}
|
||
encrypt_body = self.sha256_hash(json.dumps(body))
|
||
timestamp = f"{int(time.time() * 1000)}"
|
||
object_id = "cc85b"
|
||
function_id = "balance_submitOrder_m"
|
||
h5st = self.get_h5st(timestamp, encrypt_body, object_id, function_id)
|
||
headers = {
|
||
"accept": "application/json, text/plain, */*",
|
||
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
|
||
"cache-control": "no-cache",
|
||
"content-type": "application/x-www-form-urlencoded",
|
||
"origin": "https://trade.m.jd.com",
|
||
"pragma": "no-cache",
|
||
"priority": "u=1, i",
|
||
"referer": "https://trade.m.jd.com/",
|
||
"sec-ch-ua": '"Chromium";v="140", "Not=A?Brand";v="24", "Microsoft Edge";v="140"',
|
||
"sec-ch-ua-mobile": "?0",
|
||
"sec-ch-ua-platform": '"Windows"',
|
||
"sec-fetch-dest": "empty",
|
||
"sec-fetch-mode": "cors",
|
||
"sec-fetch-site": "same-site",
|
||
"user-agent": self.user_agent,
|
||
"x-referer-page": "https://trade.m.jd.com/pay",
|
||
"x-rp-client": "h5_1.0.0",
|
||
"cookie": self.cookies,
|
||
}
|
||
data = {
|
||
"scval": self.sku_id,
|
||
"body": json.dumps(body),
|
||
"t": timestamp,
|
||
"h5st": h5st,
|
||
"appid": "m_core",
|
||
"client": "Win32",
|
||
"clientVersion": "2.5.2",
|
||
"d_brand": "",
|
||
"d_model": "",
|
||
"functionId": "balance_submitOrder_m",
|
||
"lang": "zh-CN",
|
||
"loginType": "2",
|
||
"networkType": "false",
|
||
"osVersion": "",
|
||
"screen": "1152*2048",
|
||
"sdkVersion": "",
|
||
"uuid": "17573259367521124301157",
|
||
"x-api-eid-token": self.x_token,
|
||
"xAPIScval2": "wx",
|
||
"xAPIScval3": "unknown",
|
||
}
|
||
url = "https://api.m.jd.com/client.action"
|
||
proxy = self._get_proxy()
|
||
response = self._session.post(
|
||
url,
|
||
headers=headers,
|
||
data=data,
|
||
verify=False,
|
||
proxies=proxy,
|
||
)
|
||
|
||
logger.info(
|
||
f"订单号:{self._order_num},app_store提交订单返回:{response.json()}"
|
||
)
|
||
return response.json()
|
||
|
||
def run(self):
|
||
self.x_token, self.eid = self.get_x_token()
|
||
# 提交预付款订单
|
||
self.get_current_order()
|
||
order_res = self.submit_order()
|
||
logger.info(
|
||
f"订单号:{self._order_num},app_store提交预付款订单返回:{order_res}"
|
||
)
|
||
# 火爆
|
||
if order_res.get("body", {}).get("errorCode") == "7201":
|
||
return BusinessCode.JD_ORDER_RISK_ERR, {
|
||
"deeplink": "",
|
||
"order_id": "",
|
||
"pay_id": "",
|
||
"remark": str(order_res),
|
||
}
|
||
# 未登录
|
||
if order_res.get("body", {}).get("errorCode") == "302":
|
||
return BusinessCode.JD_ORDER_CK_ERR, {
|
||
"deeplink": "",
|
||
"order_id": "",
|
||
"pay_id": "",
|
||
"remark": order_res.get("body", {}).get("errorReason"),
|
||
}
|
||
# 无货
|
||
if order_res.get("body", {}).get("errorCode") == "722":
|
||
return BusinessCode.JD_ORDER_STOCK_ERR, {
|
||
"deeplink": "",
|
||
"order_id": "",
|
||
"pay_id": "",
|
||
"remark": order_res.get("body", {})
|
||
.get("submitOrderPromptVO", {})
|
||
.get("title"),
|
||
}
|
||
# 火爆
|
||
if order_res.get("body", {}).get("errorCode") == "601":
|
||
return BusinessCode.JD_ORDER_RISK_ERR, {
|
||
"deeplink": "",
|
||
"order_id": "",
|
||
"pay_id": "",
|
||
"remark": str(order_res),
|
||
}
|
||
if order_res.get("code") != "0":
|
||
return BusinessCode.JD_ORDER_NORMAL_ERR, {
|
||
"deeplink": "",
|
||
"order_id": "",
|
||
"pay_id": "",
|
||
"remark": str(order_res),
|
||
}
|
||
if order_res.get("body", {}).get("errorCode") == "601":
|
||
return BusinessCode.JD_ORDER_NORMAL_ERR, {
|
||
"deeplink": "",
|
||
"order_id": "",
|
||
"pay_id": "",
|
||
"remark": str(order_res),
|
||
}
|
||
order_id = order_res.get("body", {}).get("order", {}).get("orderId")
|
||
# 获取支付信息
|
||
pay_res = self.get_pay_res(order_id)
|
||
logger.info(f"订单号:{self._order_num},app_store获取支付信息返回:{pay_res}")
|
||
if (
|
||
order_res.get("body", {}).get("errorCode") == "302"
|
||
and order_res.get("body", {}).get("errorReason") == "未登录"
|
||
):
|
||
return BusinessCode.JD_ORDER_CK_ERR, {
|
||
"deeplink": "",
|
||
"order_id": "",
|
||
"pay_id": "",
|
||
"remark": str(order_res),
|
||
}
|
||
if pay_res.get("code") != "0":
|
||
return BusinessCode.JD_ORDER_NORMAL_ERR, {
|
||
"deeplink": "",
|
||
"order_id": "",
|
||
"pay_id": "",
|
||
"remark": str(pay_res),
|
||
}
|
||
pay_id = pay_res["body"]["payId"]
|
||
# 获取微信支付信息
|
||
return self.refresh_payment_url(pay_id, order_id)
|
||
|
||
def refresh_payment_url(self, pay_id: str, order_id: int):
|
||
logger.info(f"订单号:{pay_id},app_store刷新支付链接 {order_id}")
|
||
pay_channel_res = self.plat_pay_channel_res(pay_id)
|
||
logger.info(
|
||
f"订单号:{self._order_num},app_store请求微信渠道返回:{pay_channel_res}"
|
||
)
|
||
if pay_channel_res.get("code") == "601":
|
||
return BusinessCode.JD_ORDER_RISK_ERR, {
|
||
"deeplink": "",
|
||
"order_id": "",
|
||
"pay_id": "",
|
||
"remark": str(pay_channel_res),
|
||
}
|
||
if pay_channel_res.get("code") != "0":
|
||
return BusinessCode.JD_ORDER_NORMAL_ERR, {
|
||
"deeplink": "",
|
||
"order_id": "",
|
||
"pay_id": "",
|
||
"remark": str(pay_channel_res),
|
||
}
|
||
wx_pay_res = self.plat_wx_pay_res(pay_id)
|
||
logger.info(
|
||
f"订单号:{self._order_num},app_store获取微信支付信息返回:{wx_pay_res}"
|
||
)
|
||
if wx_pay_res.get("code") != "0":
|
||
return BusinessCode.JD_ORDER_NORMAL_ERR, {
|
||
"deeplink": "",
|
||
"order_id": "",
|
||
"pay_id": "",
|
||
"remark": str(wx_pay_res),
|
||
}
|
||
if wx_pay_res.get("errorCode") == "-1":
|
||
return BusinessCode.JD_ORDER_CK_ERR, {
|
||
"deeplink": "",
|
||
"order_id": "",
|
||
"pay_id": "",
|
||
"remark": str(wx_pay_res),
|
||
}
|
||
return BusinessCode.SUCCESS, {
|
||
"deeplink": wx_pay_res.get("payInfo", {}).get("mweb_url"),
|
||
"order_id": str(order_id),
|
||
"pay_id": str(pay_id),
|
||
}
|