添加支付场景

This commit is contained in:
db_huang 2026-10-30 15:58:12 +08:00
parent e70866c4b6
commit 8f07b6bcf1
7 changed files with 23 additions and 4 deletions

View File

@ -52,4 +52,5 @@ ALIPAY_FORMAT=json
ALIPAY_NOTIFY_URL=https://your-domain.example.com/alipay_callback ALIPAY_NOTIFY_URL=https://your-domain.example.com/alipay_callback
ALIPAY_TRANSFER_API=alipay.fund.trans.uni.transfer ALIPAY_TRANSFER_API=alipay.fund.trans.uni.transfer
ALIPAY_TRANSFER_QUERY_API=alipay.fund.trans.common.query ALIPAY_TRANSFER_QUERY_API=alipay.fund.trans.common.query
ALIPAY_TRANSFER_SCENE_NAME=佣金报酬
ALIPAY_HTTP_TIMEOUT_SECONDS=30 ALIPAY_HTTP_TIMEOUT_SECONDS=30

View File

@ -27,6 +27,7 @@ def validate_configuration() -> None:
("ALIPAY_PAYER_ACCOUNT", settings.alipay_payer_account), ("ALIPAY_PAYER_ACCOUNT", settings.alipay_payer_account),
("ALIPAY_APP_PRIVATE_KEY_PATH", settings.alipay_app_private_key_path), ("ALIPAY_APP_PRIVATE_KEY_PATH", settings.alipay_app_private_key_path),
("ALIPAY_PUBLIC_KEY_PATH 或 ALIPAY_ALIPAY_PUBLIC_CERT_PATH", settings.alipay_public_key_path or settings.alipay_alipay_public_cert_path), ("ALIPAY_PUBLIC_KEY_PATH 或 ALIPAY_ALIPAY_PUBLIC_CERT_PATH", settings.alipay_public_key_path or settings.alipay_alipay_public_cert_path),
("ALIPAY_TRANSFER_SCENE_NAME", settings.alipay_transfer_scene_name),
) if not str(value or "").strip() ) if not str(value or "").strip()
] ]
if missing: if missing:
@ -265,6 +266,7 @@ def transfer(*, out_biz_no: str, amount_fen: int, account: str, payee_name: str,
model.trans_amount = f"{Decimal(amount_fen) / Decimal(100):.2f}" model.trans_amount = f"{Decimal(amount_fen) / Decimal(100):.2f}"
model.product_code = "TRANS_ACCOUNT_NO_PWD" model.product_code = "TRANS_ACCOUNT_NO_PWD"
model.biz_scene = "DIRECT_TRANSFER" model.biz_scene = "DIRECT_TRANSFER"
model.transfer_scene_name = settings.alipay_transfer_scene_name
model.order_title = order_title[:128] model.order_title = order_title[:128]
payee = Participant() payee = Participant()
payee.identity = account payee.identity = account
@ -299,6 +301,7 @@ def query(*, out_biz_no: str) -> dict:
model = AlipayFundTransCommonQueryModel() model = AlipayFundTransCommonQueryModel()
model.out_biz_no = out_biz_no model.out_biz_no = out_biz_no
model.product_code = "TRANS_ACCOUNT_NO_PWD" model.product_code = "TRANS_ACCOUNT_NO_PWD"
model.biz_scene = "DIRECT_TRANSFER"
request = AlipayFundTransCommonQueryRequest(biz_model=model) request = AlipayFundTransCommonQueryRequest(biz_model=model)
try: try:
raw = _client().execute(request) raw = _client().execute(request)

View File

@ -77,6 +77,7 @@ class Settings:
alipay_notify_url = os.getenv("ALIPAY_NOTIFY_URL", "") alipay_notify_url = os.getenv("ALIPAY_NOTIFY_URL", "")
alipay_transfer_api = os.getenv("ALIPAY_TRANSFER_API", "alipay.fund.trans.uni.transfer") alipay_transfer_api = os.getenv("ALIPAY_TRANSFER_API", "alipay.fund.trans.uni.transfer")
alipay_transfer_query_api = os.getenv("ALIPAY_TRANSFER_QUERY_API", "alipay.fund.trans.common.query") alipay_transfer_query_api = os.getenv("ALIPAY_TRANSFER_QUERY_API", "alipay.fund.trans.common.query")
alipay_transfer_scene_name = os.getenv("ALIPAY_TRANSFER_SCENE_NAME", "").strip()
alipay_http_timeout_seconds = int(os.getenv("ALIPAY_HTTP_TIMEOUT_SECONDS", "30")) alipay_http_timeout_seconds = int(os.getenv("ALIPAY_HTTP_TIMEOUT_SECONDS", "30"))

View File

@ -16,19 +16,29 @@ class FakeClient:
return json.dumps(self.payload, ensure_ascii=False) return json.dumps(self.payload, ensure_ascii=False)
class CapturingClient(FakeClient):
def execute(self, request):
self.params = request.get_params()
return super().execute(request)
def test_transfer_parses_official_sdk_json_response(monkeypatch): def test_transfer_parses_official_sdk_json_response(monkeypatch):
monkeypatch.setattr(alipay_provider, "_client", lambda: FakeClient({ client = CapturingClient({
"code": "10000", "code": "10000",
"msg": "Success", "msg": "Success",
"out_biz_no": "RF001", "out_biz_no": "RF001",
"order_id": "ALI001", "order_id": "ALI001",
"status": "SUCCESS", "status": "SUCCESS",
})) })
monkeypatch.setattr(alipay_provider, "_client", lambda: client)
monkeypatch.setattr(alipay_provider.settings, "alipay_transfer_scene_name", "佣金报酬")
result = alipay_provider.transfer( result = alipay_provider.transfer(
out_biz_no="RF001", amount_fen=300, account="buyer@example.com", out_biz_no="RF001", amount_fen=300, account="buyer@example.com",
payee_name="测试收款人", order_title="测试返款", payee_name="测试收款人", order_title="测试返款",
) )
assert result == {"out_biz_no": "RF001", "trade_no": "ALI001", "status": "SUCCESS"} assert result == {"out_biz_no": "RF001", "trade_no": "ALI001", "status": "SUCCESS"}
biz_content = json.loads(client.params["biz_content"])
assert biz_content["transfer_scene_name"] == "佣金报酬"
def test_transfer_preserves_provider_business_error(monkeypatch): def test_transfer_preserves_provider_business_error(monkeypatch):
@ -66,16 +76,20 @@ def test_old_sdk_error_envelope_is_recovered_from_response_exception():
def test_query_parses_processing_status(monkeypatch): def test_query_parses_processing_status(monkeypatch):
monkeypatch.setattr(alipay_provider, "_client", lambda: FakeClient({ client = CapturingClient({
"code": "10000", "code": "10000",
"msg": "Success", "msg": "Success",
"out_biz_no": "RF003", "out_biz_no": "RF003",
"order_id": "ALI003", "order_id": "ALI003",
"status": "DEALING", "status": "DEALING",
})) })
monkeypatch.setattr(alipay_provider, "_client", lambda: client)
result = alipay_provider.query(out_biz_no="RF003") result = alipay_provider.query(out_biz_no="RF003")
assert result["status"] == "DEALING" assert result["status"] == "DEALING"
assert result["trade_no"] == "ALI003" assert result["trade_no"] == "ALI003"
biz_content = json.loads(client.params["biz_content"])
assert biz_content["biz_scene"] == "DIRECT_TRANSFER"
assert biz_content["product_code"] == "TRANS_ACCOUNT_NO_PWD"
def test_legacy_transfer_table_is_migrated_without_losing_rows(): def test_legacy_transfer_table_is_migrated_without_losing_rows():