payment.controller.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. /**
  2. * 支付控制器:创建支付 / 查询状态 / 模拟成功(仅 mock)
  3. */
  4. const express = require('express');
  5. const config = require('../config');
  6. const { ok, fail } = require('../utils/response');
  7. const gateway = require('../services/pay_gateway.service');
  8. const orderService = require('../services/order.service');
  9. const router = express.Router();
  10. /**
  11. * 创建支付
  12. * POST /v1/payment/:channel/
  13. * body: { product_id, source?: 'app'|'web', currency?: 'usd'|'cny' }
  14. */
  15. router.post('/:channel/', async (req, res) => {
  16. try {
  17. const { channel } = req.params;
  18. const { product_id, source = 'app', currency } = req.body || {};
  19. const data = await gateway.createPayment({ channel, productId: product_id, source, currency });
  20. return ok(res, data);
  21. } catch (e) {
  22. const status = e.code === 'PRODUCT_NOT_FOUND' ? 404 : e.code === 'BAD_CHANNEL' ? 400 : 500;
  23. return fail(res, status, e.code || 'PAYMENT_CREATE_FAILED', e.message);
  24. }
  25. });
  26. /**
  27. * 查询支付状态(前端轮询/最终确认)
  28. * GET /v1/payment/:payment_id
  29. */
  30. router.get('/:payment_id', (req, res) => {
  31. return ok(res, orderService.getStatus(req.params.payment_id));
  32. });
  33. /**
  34. * 模拟支付结果(仅 MOCK_MODE):走与真实回调相同的 markPaid 幂等流程
  35. * POST /v1/payment/simulate/:result result: success|fail
  36. * body: { payment_id }
  37. */
  38. router.post('/simulate/:result', (req, res) => {
  39. if (!config.mock) {
  40. return fail(res, 403, 'MOCK_DISABLED', 'simulate only available in MOCK_MODE');
  41. }
  42. const { payment_id } = req.body || {};
  43. const result = req.params.result;
  44. if (!payment_id) return fail(res, 400, 'BAD_REQUEST', 'payment_id required');
  45. let changed = false;
  46. if (result === 'success') {
  47. changed = orderService.markPaid(payment_id, { channel: 'mock', channelTradeNo: `mock_${payment_id}` });
  48. } else {
  49. changed = Boolean(orderService.getOrder(payment_id));
  50. }
  51. return ok(res, { payment_id, simulated: changed, result });
  52. });
  53. module.exports = router;