Skip to main content
Glama

query_yeepay_payment_status

Check the status of Yeepay payments by querying with the merchant order ID to verify transaction details and ensure accurate payment processing.

Instructions

查询支付状态工具

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
orderIdYes商户订单号

Implementation Reference

  • src/index.ts:67-94 (registration)
    MCP server registration of the 'query_yeepay_payment_status' tool, defining input schema and thin wrapper handler that calls the core queryYeepayPaymentStatus function.
    server.tool( "query_yeepay_payment_status", "查询支付状态工具", QueryPaymentStatusInputSchema.shape, // Pass the shape async (input: QueryPaymentStatusInput) => { // Zod schema handles validation try { // Dynamically import the module to avoid circular dependencies const { queryYeepayPaymentStatus } = await import( "./tools/queryPayment.js" ); const queryResult = await queryYeepayPaymentStatus(input); return { content: [ { type: "text" as const, text: JSON.stringify(queryResult, null, 2) }, ], }; } catch (error) { console.error( "Error caught in query_yeepay_payment_status tool handler:", error, ); throw error; // Let SDK handle the error } }, );
  • The core handler logic for querying Yeepay payment status, called by the MCP tool registration. Uses YopClient to make GET request to Yeepay API.
    export async function queryYeepayPaymentStatus(input: QueryRequest): Promise<YeepayQueryResult> { try { const { parentMerchantNo, merchantNo, appKey, appPrivateKey } = appConfig; const yopConfig: YopConfig = { appKey, appPrivateKey, }; const yopClient = new YopClient(yopConfig); const queryParams = { parentMerchantNo, merchantNo, orderId: input.orderId }; console.info("[QueryPayment] Request Params:", JSON.stringify(queryParams, null, 2)); const apiUrl = '/rest/v1.0/trade/order/query'; // Add double assertion for consistency, similar to the post method usage const responseData = await yopClient.get(apiUrl, queryParams as unknown as Record<string, unknown>) as YeepayQueryResponse; // 使用 SDK 的 get 方法 console.info("[QueryPayment] Raw Response Data:", JSON.stringify(responseData, null, 2)); // 打印原始响应 if (responseData && responseData.state === 'SUCCESS') { if (responseData.result && responseData.result.code === 'OPR00000') { // 成功状态且业务码为 OPR00000 console.info("[QueryPayment] Success:", JSON.stringify(responseData.result)); return responseData.result; } else { // 成功状态但业务码非 OPR00000,表示业务失败 const errorCode = responseData.result?.code || 'UNKNOWN_CODE'; const errorMessage = responseData.result?.message || 'Unknown Yeepay business error message'; const errorLog = `[QueryPayment] Yeepay API Business Error (state: SUCCESS): Code=${errorCode}, Message=${errorMessage}`; console.error(errorLog); throw new Error(`Yeepay Business Error: ${errorCode} - ${errorMessage}`); } } else if (responseData && responseData.state === 'FAILURE') { // Failure state const errorCode = responseData.error?.code || 'UNKNOWN_FAILURE_CODE'; const errorMessage = responseData.error?.message || 'Unknown Yeepay failure message'; const errorLog = `[QueryPayment] Yeepay API Failure (state: FAILURE): Code=${errorCode}, Message=${errorMessage}`; console.error(errorLog); throw new Error(`Yeepay API Failure: ${errorCode} - ${errorMessage}`); } else { // Unknown state or other unexpected response structure const errorLog = `[QueryPayment] Unknown or Unexpected Yeepay API Response State: ${responseData?.state || 'State Undefined'}. Response: ${JSON.stringify(responseData)}`; console.error(errorLog); throw new Error(`Unknown Yeepay API response state: ${responseData?.state}`); } } catch (error: unknown) { // Catch standardized errors from YopClient or other errors within this function console.error("[QueryPayment] Overall Error:", error); // Re-throw the error directly if (error instanceof Error) { throw error; } else { throw new Error(`Unknown error in queryYeepayPaymentStatus: ${String(error)}`); } } }
  • Zod schema defining the input parameters for the query_yeepay_payment_status tool (orderId: string).
    // Define Zod schema for query payment status input const QueryPaymentStatusInputSchema = z.object({ orderId: z.string().describe("商户订单号"), }); type QueryPaymentStatusInput = z.infer<typeof QueryPaymentStatusInputSchema>;
  • TypeScript interfaces defining input (QueryRequest), output (YeepayQueryResult), and internal response structures for type safety.
    // Expected structure for a successful query result export interface YeepayQueryResult { // Add export code: string; message: string; orderId: string; uniqueOrderNo: string; status: string; // e.g., 'PROCESSING', 'SUCCESS', 'FAILED' } // Expected structure for a query error interface YeepayQueryError { code: string; message: string; } // Complete SDK response structure interface YeepayQueryResponse { state: 'SUCCESS' | 'FAILURE' | string; result?: YeepayQueryResult; error?: YeepayQueryError; } export interface QueryRequest { // Add export orderId: string; } export async function queryYeepayPaymentStatus(input: QueryRequest): Promise<YeepayQueryResult> { try { const { parentMerchantNo, merchantNo, appKey, appPrivateKey } = appConfig; const yopConfig: YopConfig = { appKey, appPrivateKey, }; const yopClient = new YopClient(yopConfig); const queryParams = { parentMerchantNo, merchantNo, orderId: input.orderId }; console.info("[QueryPayment] Request Params:", JSON.stringify(queryParams, null, 2)); const apiUrl = '/rest/v1.0/trade/order/query'; // Add double assertion for consistency, similar to the post method usage const responseData = await yopClient.get(apiUrl, queryParams as unknown as Record<string, unknown>) as YeepayQueryResponse; // 使用 SDK 的 get 方法 console.info("[QueryPayment] Raw Response Data:", JSON.stringify(responseData, null, 2)); // 打印原始响应 if (responseData && responseData.state === 'SUCCESS') { if (responseData.result && responseData.result.code === 'OPR00000') { // 成功状态且业务码为 OPR00000 console.info("[QueryPayment] Success:", JSON.stringify(responseData.result)); return responseData.result; } else { // 成功状态但业务码非 OPR00000,表示业务失败 const errorCode = responseData.result?.code || 'UNKNOWN_CODE'; const errorMessage = responseData.result?.message || 'Unknown Yeepay business error message'; const errorLog = `[QueryPayment] Yeepay API Business Error (state: SUCCESS): Code=${errorCode}, Message=${errorMessage}`; console.error(errorLog); throw new Error(`Yeepay Business Error: ${errorCode} - ${errorMessage}`); } } else if (responseData && responseData.state === 'FAILURE') { // Failure state const errorCode = responseData.error?.code || 'UNKNOWN_FAILURE_CODE'; const errorMessage = responseData.error?.message || 'Unknown Yeepay failure message'; const errorLog = `[QueryPayment] Yeepay API Failure (state: FAILURE): Code=${errorCode}, Message=${errorMessage}`; console.error(errorLog); throw new Error(`Yeepay API Failure: ${errorCode} - ${errorMessage}`); } else { // Unknown state or other unexpected response structure const errorLog = `[QueryPayment] Unknown or Unexpected Yeepay API Response State: ${responseData?.state || 'State Undefined'}. Response: ${JSON.stringify(responseData)}`; console.error(errorLog); throw new Error(`Unknown Yeepay API response state: ${responseData?.state}`); } } catch (error: unknown) { // Catch standardized errors from YopClient or other errors within this function console.error("[QueryPayment] Overall Error:", error); // Re-throw the error directly if (error instanceof Error) { throw error; } else { throw new Error(`Unknown error in queryYeepayPaymentStatus: ${String(error)}`); } } }
  • Alternative standalone handler export for a tool runtime, implementing full logic including validation, SDK init with hardcoded creds, API call, and error handling for query_yeepay_payment_status.
    export async function handler({ input, logger }: Args<Input>): Promise<Output> { // 0. Input Validation try { if (!input || typeof input !== 'object') { throw new Error('Missing or invalid event object.'); } // Required parameters const requiredFields = ['orderId']; const missingFields = requiredFields.filter(key => !input[key]); if (missingFields.length > 0) { throw new Error(`Missing required fields in event object: ${missingFields.join(', ')}`); } } catch (error) { logger.error('Input validation failed:', error.message); return { error: 'INVALID_PARAMETERS', message: error.message, }; } try { // 2. Prepare Request Data const queryParams = { parentMerchantNo: '10086032562', merchantNo: '10086039518', orderId: input.orderId }; logger.debug('Prepared query parameters:', JSON.stringify(queryParams)); // Use dynamic import() for ES modules const sdk = await import('@yeepay/yop-typescript-sdk'); const YopClient = sdk.YopClient; if (!YopClient) { throw new Error('Could not find YopClient in the dynamically imported module'); } logger.info('YopClient loaded from dynamic import'); // Initialize YopClient with config const yopClientInstance = new YopClient({ appKey: 'app_10086032562', appPrivateKey: 'MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDdnBKx03zrrPzJ/Z8rJMEaYvmes19qIPGcgncUQNOYauaXy99iT2P3O1H3qZceKZ8ngeha5ckuV4ke3tLlMRHn3GvTzd1l6EEntwL6SRUopmhj/635bkGUlQvEZrWAtwfO0wcoI0XnRB3JLc+r8nTf64vIi2UovqcZ6LKJj96btie7rYZZqqtr2+e7S0HDqH6nHcqvBYVGYGrYnDNKyjSvKdjGIq+JMQu1tJOtqT4JoeFAOBSTw3Jqkpvnudc1GgWVOepuGVyaXHXVNQTjnap7LMbJ+IJXBLSgGi1uC4u8Ypc2u0kDLXKkff0X/DG9cJXMaLcf/3yBH2/UoebTTJudAgMBAAECggEACptTfrzlW/9b2wwfT+iSsIFfurORo8n/XnMVIXxH1GH7dvT8VF+B5J2reuvcToaF9lVeqmkYo7XvW3GlTPB4D62qYIkYKW5AHhdBlnqkf11VnkGo0UkwbNzkYwpachZwknrhuw9TI3JMbapaZ/uzEdubhWX8mcJkS5ZqYzCmYjPzKfYMuowZ4ygOETOER9pl8J7dt4CYYI+GLwVT39D6ptf74fzlKohT506ulLUu3AWsavvW3QTPSxzS2ARO7QaLco8Dly8AJiGmSUdwSzzwVgYD1kVHtUUukbtnjFBTN8PqGt+TM+gcv8s5LlaZSYp4Zlwt9LTdW2sFCSoRj8HLaQKBgQD3u6c2PyRckNpwGuOjTJHy+uF7OGoiFyuGAxmyC8UzNG+nLBghZjCJmzkfzKrjNINrNT4zxepXhKurW0vxd9ZSkjpyEteRDSfdyvsDEbfR3p6w9ObA8iZkCvesYchrwrdWO7V4sjynvEhWkLSctLWaASbj7zuyYu0OYiSo28MN+QKBgQDlAUB3mLEpBvWIlMnXhfz/RrmEqlg6yygu37Xjjs7wjyPSz3RqUIB2YYT9d5wGob2nBLD4IvoSWvysNegt0TiklAHYW7LNW1DB1Oo0M5xOgToOOA545aR8DG9XJGOlKRiGJQS0q9T4X4z1TOx93W8bzNeUZgL5Kk5WQE8cuUxzxQKBgQC4nhgWzSeD9E9VjDRo1f9OXLj84yX1Ed9Vl6nmje8AIeuzYaD6AvXZFtyTXitb9x6ZHqykWLIzVqO4p+kIoo4OKvtzV6deabd0CnjV6LZcqNMKfPgaglsp4yKATL7Xz9xhX032DJ43QpGGMYDn56QOiR06cGbEogSX23wGev/5wQKBgQCMQc8FMNzYnu2FAHP675J7mwqG6XnuUH1E8DlLrSyrg0/SjsLjVnjHiITWZQqHuUoZ4DKvV2TIFzgIFWAlp63Ehu32YHtLcTEt9kSXQkDqiBVRnh2nCCdM3qTWv2/UOS5PAp82NMPUd1ky6DE0CYpCgZxLxIrvpmyiQPLzSb48bQKBgAF0EpSRsPQhPjUYsPc3FA71R0GSRyxr9ktM5hqsG/qrh0ep4jIFKibGA+VJo/ed2QC4MNAjPR285v6ytBcFyoEAacf7noSavVvYU5/KaQ5wJYSue0+M5IBJrrwLv0k1ppe86Xp8890NT2XHbaALY3hcSBTGs2aHPUNEma7H+2T9', yopApiBaseUrl: 'https://openapi-a.yeepay.com', yopPublicKey: 'MIIE2TCCA8GgAwIBAgIFQ5cTlZgwDQYJKoZIhvcNAQELBQAwWDELMAkGA1UEBhMCQ04xMDAuBgNVBAoMJ0NoaW5hIEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEXMBUGA1UEAwwOQ0ZDQSBBQ1MgT0NBMzEwHhcNMjEwNDI1MDIwOTAwWhcNMjMwNDI1MDIwOTAwWjCBhzELMAkGA1UEBhMCQ04xFzAVBgNVBAoMDkNGQ0EgQUNTIE9DQTMxMRAwDgYDVQQLDAdURVNUIFJBMRkwFwYDVQQLDBBPcmdhbmlzYXRpb25hbC0xMTIwMAYDVQQDDCkwNTFA5piT5a6d5byA5pS+5bmz5Y+wQDMxMTAwMDAwMDU4MDQyMjlANTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOqdF1o7HGPoLMqikYcPTHi7BJoRXQUYU9npjnJPxdTpsN/GVoScYfZA37OR8xSTK1aM4FPkiRQzjcbPFAdMDCCykZqny3HwpRvTMgjbiZJH5tBxUL9YURnTr2T149wXJLsGuxaxFwUWFISu7yeNGn7prKbYZrHum7OpmcTZ/5gC2dl9O7s5zq63Nq5ONWNh37XbsWcOk+BJrVrjdseAmfIMEsjwFuWc2SS0OrWQ6IwSuBmUwBoZ5924OWwbAZcNvhS5AkAbg7CVbBT4hof2+iv/sxk71slHLvi1I9jHo2EBCwzt4tr0F1Q5O5VYtv03FGHn7yHLLJ87Hwn42qK8bLsCAwEAAaOCAXgwggF0MGwGCCsGAQUFBwEBBGAwXjAoBggrBgEFBQcwAYYcaHR0cDovL29jc3AuY2ZjYS5jb20uY24vb2NzcDAyBggrBgEFBQcwAoYmaHR0cDovL2NybC5jZmNhLmNvbS5jbi9vY2EzMS9vY2EzMS5jZXIwHwYDVR0jBBgwFoAU4rQJy81hoXNKeX/xioML3bR+jB0wDAYDVR0TAQH/BAIwADBIBgNVHSAEQTA/MD0GCGCBHIbvKgEEMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2ZjYS5jb20uY24vdXMvdXMtMTQuaHRtMD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly9jcmwuY2ZjYS5jb20uY24vb2NhMzEvUlNBL2NybDMwMjAuY3JsMA4GA1UdDwEB/wQEAwIGwDAdBgNVHQ4EFgQU4swobhCzosrPL4Gv8clxRwbHy0EwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEBCwUAA4IBAQBpZpClbx+FJo5WpuJW+TJKYRayKeAx3/+VvlMyWvdcbABPlvwBY1m3xl1k+tsqqtBGvjathGmw1w7YESdRFTT/ty04MDLmz62USS4DJlZ2EWMxPm0bKpuAPsWb3+EtvizyZ0l1gX/D0YHDcH+VljYlGAv+yQEUzD+0c9NZSWr4V19yRVDQEicll5hJko7RFQUrwW+wNSrexzlyQFbUlbljwAnHO0TF3zgTXKRu2YNiKZGlxr28FjOeMQdvpiNqHCW9ACjQqL0vz1l9IImn0lm+0vh0YhAN0oFzJZvs5lFG9Bg+kNkyhgf9eVcUUxXKnA6UwXq2amoTa4Iq3NW6YuPI' }); logger.info('YopClient initialized successfully'); // 4. Define API URI const apiUri = '/rest/v1.0/trade/order/query'; // 5. API Call const response = await yopClientInstance.get(apiUri, queryParams); logger.debug('API Response:', JSON.stringify(response)); // 6. Result Handling const isProduction = process.env.NODE_ENV === 'production'; // Check env for logging control if (response && response.result) { const resultData = response.result; logger.info('YeePay API query successful.'); const queryResponse = { code: resultData.code, message: resultData.message, orderId: resultData.orderId, uniqueOrderNo: resultData.uniqueOrderNo, status: resultData.status, orderAmount: resultData.orderAmount, payAmount: resultData.payAmount }; logger.debug('Processed successful response:', JSON.stringify(queryResponse)); return queryResponse; } else { logger.error('YeePay API call failed or returned an error state.'); const errorDetails = response ? (response.error || response.result || response) : 'No response object'; logger.error('Error details:', JSON.stringify(errorDetails)); /** @type {YeePayError} */ const errorResponse = { error: response?.error?.code || response?.result?.code || 'YOP_API_ERROR', message: response?.error?.message || response?.result?.message || 'Unknown YeePay API error', subCode: response?.error?.subCode, subMessage: response?.error?.subMessage, rawResponse: !isProduction ? response : undefined, }; return errorResponse; } } catch (error) { logger.error('An unexpected error occurred during YeePay payment status query:', error); if (error.stack) { logger.error('Stack trace:', error.stack); } return { error: 'INTERNAL_SERVER_ERROR', message: error.message || 'An unexpected error occurred.', }; } };

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yop-platform/yeepay-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server