@ar-agents/mercadopago 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/index.cjs +796 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +714 -4
- package/dist/index.d.ts +714 -4
- package/dist/index.js +779 -49
- package/dist/index.js.map +1 -1
- package/dist/otel.cjs +102 -0
- package/dist/otel.cjs.map +1 -0
- package/dist/otel.d.cts +90 -0
- package/dist/otel.d.ts +90 -0
- package/dist/otel.js +100 -0
- package/dist/otel.js.map +1 -0
- package/package.json +19 -1
- package/tools.manifest.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { I as IdempotencyCache, S as SubscriptionStateAdapter } from './state-C6Wzb_XX.cjs';
|
|
3
|
+
export { a as InMemoryIdempotencyCache, b as InMemoryOAuthTokenStore, c as InMemoryStateAdapter, O as OAuthTokenRecord, d as OAuthTokenStore, e as SubscriptionStateRecord } from './state-C6Wzb_XX.cjs';
|
|
2
4
|
import { ToolSet } from 'ai';
|
|
3
|
-
import { S as SubscriptionStateAdapter } from './state-C6Wzb_XX.cjs';
|
|
4
|
-
export { I as IdempotencyCache, a as InMemoryIdempotencyCache, b as InMemoryOAuthTokenStore, c as InMemoryStateAdapter, O as OAuthTokenRecord, d as OAuthTokenStore, e as SubscriptionStateRecord } from './state-C6Wzb_XX.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Circuit breaker — protects your app from cascading failures when MP
|
|
@@ -1876,6 +1876,338 @@ declare class MercadoPagoClient {
|
|
|
1876
1876
|
}>;
|
|
1877
1877
|
}
|
|
1878
1878
|
|
|
1879
|
+
/**
|
|
1880
|
+
* Webhook idempotency / dedup — short-circuits duplicate webhook deliveries
|
|
1881
|
+
* from MP to prevent double-processing.
|
|
1882
|
+
*
|
|
1883
|
+
* # The problem
|
|
1884
|
+
*
|
|
1885
|
+
* MP retries webhook deliveries on 5xx responses. The retry policy is
|
|
1886
|
+
* exponential backoff: 5min, 15min, 30min, 1h, 6h, 24h, 48h, 96h, 192h
|
|
1887
|
+
* (~12 attempts over 8 days). If your handler temporarily 5xx'd (DB
|
|
1888
|
+
* down, deploy in progress, etc.) and then recovered, you'll receive
|
|
1889
|
+
* the SAME webhook 5+ times. Without dedup:
|
|
1890
|
+
*
|
|
1891
|
+
* - You double-charge (if the webhook triggers a charge)
|
|
1892
|
+
* - You double-send notifications (5 emails to the buyer instead of 1)
|
|
1893
|
+
* - You double-create downstream resources
|
|
1894
|
+
*
|
|
1895
|
+
* # The fix
|
|
1896
|
+
*
|
|
1897
|
+
* Cache the unique "delivery key" of every webhook you've successfully
|
|
1898
|
+
* processed. On retry, recognize the key, return 200 immediately, skip
|
|
1899
|
+
* processing.
|
|
1900
|
+
*
|
|
1901
|
+
* # The "delivery key"
|
|
1902
|
+
*
|
|
1903
|
+
* MP doesn't ship a single canonical id per delivery, but the tuple
|
|
1904
|
+
* `${topic}:${dataId}:${requestId}` is stable for retries (same delivery
|
|
1905
|
+
* attempt → same x-request-id) and unique enough to dedupe.
|
|
1906
|
+
*
|
|
1907
|
+
* # Storage
|
|
1908
|
+
*
|
|
1909
|
+
* Reuse `IdempotencyCache` from `state.ts`. Default TTL: 7 days (matches
|
|
1910
|
+
* MP's webhook retry window). Override per-deployment.
|
|
1911
|
+
*/
|
|
1912
|
+
|
|
1913
|
+
interface WebhookDedupOptions {
|
|
1914
|
+
/**
|
|
1915
|
+
* Storage for processed webhook ids. Plug in `VercelKVIdempotencyCache`
|
|
1916
|
+
* for production or `InMemoryIdempotencyCache` for tests.
|
|
1917
|
+
*/
|
|
1918
|
+
cache: IdempotencyCache;
|
|
1919
|
+
/**
|
|
1920
|
+
* Time-to-live for dedup entries (seconds). Default 7 days — covers MP's
|
|
1921
|
+
* full retry window (~8 days) with a safety margin.
|
|
1922
|
+
*/
|
|
1923
|
+
ttlSeconds?: number;
|
|
1924
|
+
/**
|
|
1925
|
+
* Optional callback fired when a duplicate is detected. Useful for
|
|
1926
|
+
* metrics ("webhooks deduped" counter).
|
|
1927
|
+
*/
|
|
1928
|
+
onDuplicate?: (deliveryKey: string) => void;
|
|
1929
|
+
}
|
|
1930
|
+
interface DedupResult {
|
|
1931
|
+
/**
|
|
1932
|
+
* `true` if this is the first time we've seen this delivery — caller
|
|
1933
|
+
* should process it.
|
|
1934
|
+
* `false` if it's a retry of a previously-seen delivery — caller should
|
|
1935
|
+
* acknowledge with 200 and skip processing.
|
|
1936
|
+
*/
|
|
1937
|
+
shouldProcess: boolean;
|
|
1938
|
+
/** The deduplication key derived from the webhook. */
|
|
1939
|
+
deliveryKey: string;
|
|
1940
|
+
}
|
|
1941
|
+
/**
|
|
1942
|
+
* Dedup helper. Use this BEFORE processing a webhook to short-circuit retries.
|
|
1943
|
+
*
|
|
1944
|
+
* @example
|
|
1945
|
+
* ```ts
|
|
1946
|
+
* import { WebhookDedup, VercelKVIdempotencyCache } from "@ar-agents/mercadopago";
|
|
1947
|
+
*
|
|
1948
|
+
* const dedup = new WebhookDedup({
|
|
1949
|
+
* cache: new VercelKVIdempotencyCache(),
|
|
1950
|
+
* onDuplicate: (key) => metrics.increment("mp.webhook.duplicate"),
|
|
1951
|
+
* });
|
|
1952
|
+
*
|
|
1953
|
+
* export async function POST(req: Request) {
|
|
1954
|
+
* const event = parseWebhookEvent(...);
|
|
1955
|
+
* if (!event) return new Response("bad request", { status: 400 });
|
|
1956
|
+
*
|
|
1957
|
+
* const requestId = req.headers.get("x-request-id");
|
|
1958
|
+
* const { shouldProcess } = await dedup.check({
|
|
1959
|
+
* topic: event.topic,
|
|
1960
|
+
* dataId: event.dataId,
|
|
1961
|
+
* requestId,
|
|
1962
|
+
* });
|
|
1963
|
+
* if (!shouldProcess) return new Response("ok (duplicate)", { status: 200 });
|
|
1964
|
+
*
|
|
1965
|
+
* // ... process the webhook ...
|
|
1966
|
+
*
|
|
1967
|
+
* return new Response("ok", { status: 200 });
|
|
1968
|
+
* }
|
|
1969
|
+
* ```
|
|
1970
|
+
*/
|
|
1971
|
+
declare class WebhookDedup {
|
|
1972
|
+
private readonly cache;
|
|
1973
|
+
private readonly ttlSeconds;
|
|
1974
|
+
private readonly onDuplicate;
|
|
1975
|
+
constructor(opts: WebhookDedupOptions);
|
|
1976
|
+
/**
|
|
1977
|
+
* Check whether a webhook delivery has been seen before. If new, mark it
|
|
1978
|
+
* as seen (so subsequent retries return shouldProcess=false). If seen,
|
|
1979
|
+
* return shouldProcess=false WITHOUT marking again.
|
|
1980
|
+
*
|
|
1981
|
+
* **Important**: this method is not atomic across concurrent calls — two
|
|
1982
|
+
* simultaneous deliveries with the same key may both pass shouldProcess=true.
|
|
1983
|
+
* For strict at-most-once processing, follow with a transaction or use a
|
|
1984
|
+
* cache that supports `setNX`-style semantics (Redis, Cloudflare KV with
|
|
1985
|
+
* conditional writes).
|
|
1986
|
+
*
|
|
1987
|
+
* For most webhook handlers this race is acceptable: even if two get
|
|
1988
|
+
* through, the downstream business logic (e.g., "charge if not already
|
|
1989
|
+
* charged") will be idempotent on its own.
|
|
1990
|
+
*/
|
|
1991
|
+
check(args: {
|
|
1992
|
+
topic: string;
|
|
1993
|
+
dataId: string;
|
|
1994
|
+
requestId: string | null;
|
|
1995
|
+
}): Promise<DedupResult>;
|
|
1996
|
+
/**
|
|
1997
|
+
* Manually mark a delivery as processed. Call this AFTER your business
|
|
1998
|
+
* logic succeeds — useful when you want to control when the dedup
|
|
1999
|
+
* marker is written (e.g., only on success).
|
|
2000
|
+
*
|
|
2001
|
+
* Combined with calling `check()` BEFORE the work, this gives "at-least-once"
|
|
2002
|
+
* semantics: failed processing → no marker → retry will be processed again.
|
|
2003
|
+
*/
|
|
2004
|
+
markProcessed(args: {
|
|
2005
|
+
topic: string;
|
|
2006
|
+
dataId: string;
|
|
2007
|
+
requestId: string | null;
|
|
2008
|
+
}): Promise<void>;
|
|
2009
|
+
/**
|
|
2010
|
+
* Variant of `check` that doesn't mark on first sight — caller must
|
|
2011
|
+
* explicitly `markProcessed` when their business logic succeeds.
|
|
2012
|
+
* Use this for at-least-once semantics (each delivery processed at
|
|
2013
|
+
* least once, possibly more if processing fails before mark).
|
|
2014
|
+
*/
|
|
2015
|
+
peekIsDuplicate(args: {
|
|
2016
|
+
topic: string;
|
|
2017
|
+
dataId: string;
|
|
2018
|
+
requestId: string | null;
|
|
2019
|
+
}): Promise<DedupResult>;
|
|
2020
|
+
private deriveKey;
|
|
2021
|
+
}
|
|
2022
|
+
|
|
2023
|
+
/**
|
|
2024
|
+
* Compute SHA-256 hash of `input`. Returns the full 64-char hex digest.
|
|
2025
|
+
*
|
|
2026
|
+
* Used for deterministic idempotency keys derived from caller-meaningful
|
|
2027
|
+
* fields. Truncate the output to 32 chars for storage if needed.
|
|
2028
|
+
*/
|
|
2029
|
+
declare function sha256Hex(input: string): Promise<string>;
|
|
2030
|
+
|
|
2031
|
+
/**
|
|
2032
|
+
* Audit logging — financial-grade compliance trail for every state-mutating
|
|
2033
|
+
* operation. Captures who/what/when/idempotency_key/before/after/result.
|
|
2034
|
+
*
|
|
2035
|
+
* # Why this is a tier-1 feature
|
|
2036
|
+
*
|
|
2037
|
+
* Every mature payment integration has an audit log. The compliance officer
|
|
2038
|
+
* asks "show me every refund issued in March 2026 by user X" and you need
|
|
2039
|
+
* to answer in <60 seconds. Without an audit log, you're trawling through
|
|
2040
|
+
* application logs hoping nothing was filtered out.
|
|
2041
|
+
*
|
|
2042
|
+
* # What gets logged
|
|
2043
|
+
*
|
|
2044
|
+
* Every **state-mutating** tool call automatically:
|
|
2045
|
+
* - `create_payment`, `charge_saved_card`, `cancel_payment`, `capture_payment`
|
|
2046
|
+
* - `refund_payment`
|
|
2047
|
+
* - `create_subscription`, `cancel/pause/resume_subscription`, `update_subscription`
|
|
2048
|
+
* - `create_order`, `capture_order`, `cancel_order`
|
|
2049
|
+
* - `create_payment_preference`, `update_payment_preference`
|
|
2050
|
+
* - `create_customer`, `update_customer`, `create_customer_card`, `delete_customer_card`
|
|
2051
|
+
* - `create_subscription_plan`, `update_subscription_plan`
|
|
2052
|
+
* - `create_store/pos`, `update_store/pos`, `delete_store/pos`
|
|
2053
|
+
* - `create_qr_payment`, `cancel_qr_payment`
|
|
2054
|
+
* - `create_point_payment_intent`, `cancel_point_payment_intent`, `update_point_device_mode`
|
|
2055
|
+
* - OAuth: `oauth_exchange_code`, `oauth_refresh_token`
|
|
2056
|
+
* - `register_bank_account`
|
|
2057
|
+
* - `create_webhook`, `update_webhook`, `delete_webhook`
|
|
2058
|
+
*
|
|
2059
|
+
* **Read-only** tools do NOT emit audit entries (would flood the log without
|
|
2060
|
+
* value): get_*, search_*, list_*, calculate_*, validate_*, lookup_*, analyze_*.
|
|
2061
|
+
*
|
|
2062
|
+
* # PII handling
|
|
2063
|
+
*
|
|
2064
|
+
* The audit log captures `inputSummary` (a deterministic hash of the input
|
|
2065
|
+
* fields, NOT the raw input) by default. Configure `redact: false` to log
|
|
2066
|
+
* raw inputs (payer email, CUIT, etc.) — only when your data-residency
|
|
2067
|
+
* policy permits.
|
|
2068
|
+
*
|
|
2069
|
+
* # Storage
|
|
2070
|
+
*
|
|
2071
|
+
* Pluggable adapter pattern. Ships:
|
|
2072
|
+
* - `InMemoryAuditLog` — for tests + single-process demos.
|
|
2073
|
+
* - `VercelKVAuditLog` (in `/vercel-kv` subpath) — production-ready, KV-backed
|
|
2074
|
+
* with daily-bucket indexing for efficient time-range queries.
|
|
2075
|
+
*
|
|
2076
|
+
* Implement your own for Postgres / S3 / SIEM integration.
|
|
2077
|
+
*/
|
|
2078
|
+
|
|
2079
|
+
type AuditOperation = "create_payment" | "charge_saved_card" | "cancel_payment" | "capture_payment" | "refund_payment" | "create_subscription" | "cancel_subscription" | "pause_subscription" | "resume_subscription" | "update_subscription" | "subscribe_to_plan" | "create_subscription_plan" | "update_subscription_plan" | "create_order" | "capture_order" | "cancel_order" | "update_order" | "create_payment_preference" | "update_payment_preference" | "create_customer" | "update_customer" | "create_customer_card" | "delete_customer_card" | "create_store" | "update_store" | "delete_store" | "create_pos" | "update_pos" | "delete_pos" | "create_qr_payment" | "cancel_qr_payment" | "create_point_payment_intent" | "cancel_point_payment_intent" | "update_point_device_mode" | "oauth_exchange_code" | "oauth_refresh_token" | "register_bank_account" | "create_webhook" | "update_webhook" | "delete_webhook" | (string & {});
|
|
2080
|
+
interface AuditEntry {
|
|
2081
|
+
/**
|
|
2082
|
+
* Unique entry id. Format: `mpaud-{ISO date}-{random}`. Use as primary
|
|
2083
|
+
* key in your storage layer.
|
|
2084
|
+
*/
|
|
2085
|
+
id: string;
|
|
2086
|
+
/** ISO 8601 timestamp. */
|
|
2087
|
+
timestamp: string;
|
|
2088
|
+
/** The MP operation performed. */
|
|
2089
|
+
operation: AuditOperation;
|
|
2090
|
+
/**
|
|
2091
|
+
* Logical actor that initiated the call. Caller-provided. Examples:
|
|
2092
|
+
* `"agent:billing-bot"`, `"user:42"`, `"cron:daily-charge"`.
|
|
2093
|
+
*
|
|
2094
|
+
* Defaults to `"unknown"` when not provided. **Always pass this in
|
|
2095
|
+
* production** — without it, your compliance trail is meaningless.
|
|
2096
|
+
*/
|
|
2097
|
+
actor: string;
|
|
2098
|
+
/** Optional tenant/seller id for multi-tenant marketplace setups. */
|
|
2099
|
+
tenantId?: string;
|
|
2100
|
+
/**
|
|
2101
|
+
* SHA-256 hex of the meaningful input fields (deterministic). Useful as
|
|
2102
|
+
* a join key with the IdempotencyCache. Does NOT contain raw PII.
|
|
2103
|
+
*/
|
|
2104
|
+
inputHash: string;
|
|
2105
|
+
/**
|
|
2106
|
+
* Optional raw input — only populated when `redact: false` was configured.
|
|
2107
|
+
* Defaults to undefined to comply with data-minimization principles.
|
|
2108
|
+
*/
|
|
2109
|
+
inputRaw?: Record<string, unknown>;
|
|
2110
|
+
/** Outcome: success or error code. */
|
|
2111
|
+
outcome: "ok" | "error";
|
|
2112
|
+
/** Error code when `outcome === "error"`. */
|
|
2113
|
+
errorCode?: string;
|
|
2114
|
+
/** Error message when `outcome === "error"`. */
|
|
2115
|
+
errorMessage?: string;
|
|
2116
|
+
/**
|
|
2117
|
+
* MP resource id created/updated by the operation (e.g., payment id).
|
|
2118
|
+
* Allows joining audit entries to the actual MP resource.
|
|
2119
|
+
*/
|
|
2120
|
+
resourceId?: string;
|
|
2121
|
+
/** Idempotency key passed to MP (for join with MP-side dedup logs). */
|
|
2122
|
+
idempotencyKey?: string;
|
|
2123
|
+
/** Duration in ms. */
|
|
2124
|
+
durationMs?: number;
|
|
2125
|
+
/** Free-form metadata bag. */
|
|
2126
|
+
metadata?: Record<string, unknown>;
|
|
2127
|
+
}
|
|
2128
|
+
interface AuditLogAdapter {
|
|
2129
|
+
append(entry: AuditEntry): Promise<void>;
|
|
2130
|
+
/** Query a time range. Optional — implementations that don't support it can omit. */
|
|
2131
|
+
query?(filter: {
|
|
2132
|
+
actor?: string;
|
|
2133
|
+
operation?: AuditOperation;
|
|
2134
|
+
tenantId?: string;
|
|
2135
|
+
from?: string;
|
|
2136
|
+
to?: string;
|
|
2137
|
+
limit?: number;
|
|
2138
|
+
}): Promise<AuditEntry[]>;
|
|
2139
|
+
}
|
|
2140
|
+
/**
|
|
2141
|
+
* Volatile, single-process audit log. Tests + dev only. Production deployments
|
|
2142
|
+
* must use a durable adapter (`VercelKVAuditLog`, your Postgres/S3 impl, etc.)
|
|
2143
|
+
*/
|
|
2144
|
+
declare class InMemoryAuditLog implements AuditLogAdapter {
|
|
2145
|
+
private readonly entries;
|
|
2146
|
+
append(entry: AuditEntry): Promise<void>;
|
|
2147
|
+
query(filter: {
|
|
2148
|
+
actor?: string;
|
|
2149
|
+
operation?: AuditOperation;
|
|
2150
|
+
tenantId?: string;
|
|
2151
|
+
from?: string;
|
|
2152
|
+
to?: string;
|
|
2153
|
+
limit?: number;
|
|
2154
|
+
}): Promise<AuditEntry[]>;
|
|
2155
|
+
/** All entries (test helper, not part of the adapter interface). */
|
|
2156
|
+
all(): AuditEntry[];
|
|
2157
|
+
reset(): void;
|
|
2158
|
+
}
|
|
2159
|
+
/**
|
|
2160
|
+
* Audit logger — the user-facing facade that builds + ships entries.
|
|
2161
|
+
*
|
|
2162
|
+
* @example
|
|
2163
|
+
* ```ts
|
|
2164
|
+
* const audit = new AuditLogger({
|
|
2165
|
+
* adapter: new InMemoryAuditLog(),
|
|
2166
|
+
* defaultActor: "agent:billing-bot",
|
|
2167
|
+
* redact: true, // default — hashes input, no raw PII
|
|
2168
|
+
* });
|
|
2169
|
+
*
|
|
2170
|
+
* const tools = mercadoPagoTools(client, {
|
|
2171
|
+
* state, backUrl, audit,
|
|
2172
|
+
* });
|
|
2173
|
+
* ```
|
|
2174
|
+
*/
|
|
2175
|
+
declare class AuditLogger {
|
|
2176
|
+
private readonly adapter;
|
|
2177
|
+
private readonly defaultActor;
|
|
2178
|
+
private readonly redact;
|
|
2179
|
+
private readonly hash;
|
|
2180
|
+
constructor(options: {
|
|
2181
|
+
adapter: AuditLogAdapter;
|
|
2182
|
+
defaultActor?: string;
|
|
2183
|
+
redact?: boolean;
|
|
2184
|
+
/** Override hash (testing). */
|
|
2185
|
+
hashFn?: typeof sha256Hex;
|
|
2186
|
+
});
|
|
2187
|
+
/**
|
|
2188
|
+
* Wrap a tool execute() function with auto-audit. The returned function:
|
|
2189
|
+
* 1. Computes inputHash before the call.
|
|
2190
|
+
* 2. Invokes the original execute().
|
|
2191
|
+
* 3. On success, appends an entry with outcome="ok" + resourceId.
|
|
2192
|
+
* 4. On failure, appends an entry with outcome="error" + errorCode/Message.
|
|
2193
|
+
* 5. Re-throws the error transparently.
|
|
2194
|
+
*/
|
|
2195
|
+
record<I, O>(args: {
|
|
2196
|
+
operation: AuditOperation;
|
|
2197
|
+
input: I;
|
|
2198
|
+
actor?: string;
|
|
2199
|
+
tenantId?: string;
|
|
2200
|
+
idempotencyKey?: string;
|
|
2201
|
+
/**
|
|
2202
|
+
* Function that extracts the resourceId from the result. Default: tries
|
|
2203
|
+
* `result.id`, `result.payment_id`, `result.subscription_id`, `result.order_id`.
|
|
2204
|
+
*/
|
|
2205
|
+
extractResourceId?: (result: O) => string | undefined;
|
|
2206
|
+
/** The actual operation to execute. */
|
|
2207
|
+
fn: () => Promise<O>;
|
|
2208
|
+
}): Promise<O>;
|
|
2209
|
+
}
|
|
2210
|
+
|
|
1879
2211
|
interface MercadoPagoToolsOptions {
|
|
1880
2212
|
/** State adapter for persisting subscription records. */
|
|
1881
2213
|
state: SubscriptionStateAdapter;
|
|
@@ -1913,8 +2245,26 @@ interface MercadoPagoToolsOptions {
|
|
|
1913
2245
|
clientId: string;
|
|
1914
2246
|
clientSecret: string;
|
|
1915
2247
|
};
|
|
2248
|
+
/**
|
|
2249
|
+
* v0.10 — Audit logger. When passed, every state-mutating tool call
|
|
2250
|
+
* automatically emits an audit entry with operation/actor/inputHash/
|
|
2251
|
+
* resourceId/outcome/duration. Read-only tools (get/search/list) skip
|
|
2252
|
+
* audit logging.
|
|
2253
|
+
*/
|
|
2254
|
+
audit?: AuditLogger;
|
|
2255
|
+
/**
|
|
2256
|
+
* v0.10 — Logical actor for audit entries (e.g., "agent:billing-bot",
|
|
2257
|
+
* "user:42"). Defaults to the AuditLogger's defaultActor.
|
|
2258
|
+
*/
|
|
2259
|
+
auditActor?: string;
|
|
2260
|
+
/**
|
|
2261
|
+
* v0.10 — Webhook deduplication for handle_webhook tool. Caches
|
|
2262
|
+
* processed (topic, dataId, requestId) tuples to short-circuit MP's
|
|
2263
|
+
* retries (which fire on 5xx and can deliver the same event 5+ times).
|
|
2264
|
+
*/
|
|
2265
|
+
webhookDedup?: WebhookDedup;
|
|
1916
2266
|
}
|
|
1917
|
-
type ToolName = "create_subscription" | "get_subscription_status" | "cancel_subscription" | "pause_subscription" | "resume_subscription" | "create_payment" | "get_payment" | "search_payments" | "cancel_payment" | "capture_payment" | "refund_payment" | "list_refunds" | "create_payment_preference" | "get_payment_preference" | "create_customer" | "find_customer_by_email" | "list_customer_cards" | "delete_customer_card" | "list_payment_methods" | "calculate_installments" | "get_account_info" | "charge_saved_card" | "create_qr_payment" | "cancel_qr_payment" | "create_subscription_plan" | "list_subscription_plans" | "update_subscription_plan" | "subscribe_to_plan" | "list_subscription_payments" | "create_store" | "list_stores" | "create_pos" | "list_pos" | "list_payment_disputes" | "get_dispute" | "list_identification_types" | "list_issuers" | "list_webhooks" | "create_webhook" | "update_webhook" | "delete_webhook" | "handle_webhook" | "oauth_authorize_url" | "oauth_exchange_code" | "oauth_refresh_token" | "create_order" | "get_order" | "update_order" | "capture_order" | "cancel_order" | "get_account_balance" | "list_account_movements" | "list_settlements" | "get_settlement" | "analyze_payment_3ds" | "get_test_cards" | "get_customer" | "update_customer" | "create_customer_card" | "get_customer_card" | "get_subscription_plan" | "update_subscription" | "search_subscriptions" | "get_refund" | "update_payment_preference" | "get_merchant_order" | "search_merchant_orders" | "update_merchant_order" | "get_store" | "update_store" | "delete_store" | "get_pos" | "update_pos" | "delete_pos" | "list_bank_accounts" | "register_bank_account" | "list_point_devices" | "update_point_device_mode" | "create_point_payment_intent" | "get_point_payment_intent" | "cancel_point_payment_intent" | "compute_marketplace_fee" | "explain_payment_status" | "mp_health_check";
|
|
2267
|
+
type ToolName = "create_subscription" | "get_subscription_status" | "cancel_subscription" | "pause_subscription" | "resume_subscription" | "create_payment" | "get_payment" | "search_payments" | "cancel_payment" | "capture_payment" | "refund_payment" | "list_refunds" | "create_payment_preference" | "get_payment_preference" | "create_customer" | "find_customer_by_email" | "list_customer_cards" | "delete_customer_card" | "list_payment_methods" | "calculate_installments" | "get_account_info" | "charge_saved_card" | "create_qr_payment" | "cancel_qr_payment" | "create_subscription_plan" | "list_subscription_plans" | "update_subscription_plan" | "subscribe_to_plan" | "list_subscription_payments" | "create_store" | "list_stores" | "create_pos" | "list_pos" | "list_payment_disputes" | "get_dispute" | "list_identification_types" | "list_issuers" | "list_webhooks" | "create_webhook" | "update_webhook" | "delete_webhook" | "handle_webhook" | "oauth_authorize_url" | "oauth_exchange_code" | "oauth_refresh_token" | "create_order" | "get_order" | "update_order" | "capture_order" | "cancel_order" | "get_account_balance" | "list_account_movements" | "list_settlements" | "get_settlement" | "analyze_payment_3ds" | "get_test_cards" | "get_customer" | "update_customer" | "create_customer_card" | "get_customer_card" | "get_subscription_plan" | "update_subscription" | "search_subscriptions" | "get_refund" | "update_payment_preference" | "get_merchant_order" | "search_merchant_orders" | "update_merchant_order" | "get_store" | "update_store" | "delete_store" | "get_pos" | "update_pos" | "delete_pos" | "list_bank_accounts" | "register_bank_account" | "list_point_devices" | "update_point_device_mode" | "create_point_payment_intent" | "get_point_payment_intent" | "cancel_point_payment_intent" | "compute_marketplace_fee" | "explain_payment_status" | "mp_health_check" | "find_applicable_promos" | "confirm_3ds_challenge" | "search_payments_all" | "list_settlements_all";
|
|
1918
2268
|
/**
|
|
1919
2269
|
* Build a tool set for the Vercel AI SDK that exposes Mercado Pago to an
|
|
1920
2270
|
* agent. Pass directly to `Experimental_Agent`'s `tools` option, or merge with
|
|
@@ -2241,6 +2591,366 @@ declare function buildTestCardScenario(cardKey: keyof typeof TEST_CARDS_AR, scen
|
|
|
2241
2591
|
* Analyze a Payment's 3DS state. Pure function, no I/O.
|
|
2242
2592
|
*/
|
|
2243
2593
|
declare function analyze3DS(payment: Payment): ThreeDSInfo;
|
|
2594
|
+
/**
|
|
2595
|
+
* Submit the 3DS challenge result back to MP after the buyer completes the
|
|
2596
|
+
* issuer challenge. Used as the FINAL step in the 3DS challenge flow:
|
|
2597
|
+
*
|
|
2598
|
+
* 1. `createPayment` returns `pending` + `pending_challenge` status_detail
|
|
2599
|
+
* 2. `analyze3DS(payment)` extracts the `challengeUrl`
|
|
2600
|
+
* 3. Buyer is redirected to `challengeUrl` and completes the challenge
|
|
2601
|
+
* 4. The issuer redirects to your `back_url` with a `challenge_complete=true`
|
|
2602
|
+
* (or similar query — depends on issuer / browser flow)
|
|
2603
|
+
* 5. **You call this method** to confirm the challenge and finalize the payment
|
|
2604
|
+
*
|
|
2605
|
+
* # Why this is separate
|
|
2606
|
+
*
|
|
2607
|
+
* Step 5 isn't documented as a SINGLE endpoint in MP's public docs — different
|
|
2608
|
+
* 3DS providers (Mastercard, Visa, Cabal) handle the challenge resolution
|
|
2609
|
+
* differently. This method tries the documented path: re-fetching the payment
|
|
2610
|
+
* via `getPayment` after the challenge — MP updates the status server-side
|
|
2611
|
+
* once the issuer reports the challenge result via their backchannel.
|
|
2612
|
+
*
|
|
2613
|
+
* # When to call
|
|
2614
|
+
*
|
|
2615
|
+
* - **Before** showing the user a final "approved/rejected" screen
|
|
2616
|
+
* - **After** the buyer is redirected back from the challenge URL
|
|
2617
|
+
* - **With backoff**: MP sometimes lags by a few seconds — recommended to
|
|
2618
|
+
* poll `getPayment` 3-5 times with 1s spacing if the first call still
|
|
2619
|
+
* returns `pending_challenge`.
|
|
2620
|
+
*/
|
|
2621
|
+
declare function confirmChallengeAndPoll(client: MercadoPagoClient, paymentId: string, options?: {
|
|
2622
|
+
/** Maximum number of polls. Default 5. */
|
|
2623
|
+
maxAttempts?: number;
|
|
2624
|
+
/** Sleep between polls in ms. Default 1000ms. */
|
|
2625
|
+
pollIntervalMs?: number;
|
|
2626
|
+
/** Optional AbortSignal to cap the total wait. */
|
|
2627
|
+
signal?: AbortSignal;
|
|
2628
|
+
}): Promise<{
|
|
2629
|
+
payment: Payment;
|
|
2630
|
+
threeDs: ThreeDSInfo;
|
|
2631
|
+
resolved: boolean;
|
|
2632
|
+
attempts: number;
|
|
2633
|
+
}>;
|
|
2634
|
+
|
|
2635
|
+
/**
|
|
2636
|
+
* Pagination helpers — automatic pagination over MP's paginated endpoints
|
|
2637
|
+
* via AsyncIterable. Replaces the manual offset/limit loop.
|
|
2638
|
+
*
|
|
2639
|
+
* # Why
|
|
2640
|
+
*
|
|
2641
|
+
* MP's paginated endpoints (search_payments, search_subscriptions,
|
|
2642
|
+
* list_account_movements, list_settlements, search_merchant_orders, etc.)
|
|
2643
|
+
* cap responses at 100 items per page. Iterating "all matching X" without
|
|
2644
|
+
* helpers means writing the offset+limit loop in every caller — annoying
|
|
2645
|
+
* + error-prone (off-by-one bugs are common).
|
|
2646
|
+
*
|
|
2647
|
+
* # Usage
|
|
2648
|
+
*
|
|
2649
|
+
* ```ts
|
|
2650
|
+
* import { paginate } from "@ar-agents/mercadopago";
|
|
2651
|
+
*
|
|
2652
|
+
* for await (const payment of paginate(
|
|
2653
|
+
* (offset) => client.searchPayments({ offset, limit: 100, status: "approved" }),
|
|
2654
|
+
* { extractItems: (page) => page.results ?? [], extractTotal: (page) => page.paging?.total ?? 0 },
|
|
2655
|
+
* )) {
|
|
2656
|
+
* console.log(payment.id);
|
|
2657
|
+
* }
|
|
2658
|
+
* ```
|
|
2659
|
+
*
|
|
2660
|
+
* Or use the convenience wrappers below:
|
|
2661
|
+
*
|
|
2662
|
+
* ```ts
|
|
2663
|
+
* for await (const payment of paginatePayments(client, { status: "approved" })) {
|
|
2664
|
+
* console.log(payment.id);
|
|
2665
|
+
* }
|
|
2666
|
+
*
|
|
2667
|
+
* // Materialize all (only when sure it fits in memory):
|
|
2668
|
+
* const allPayments = await collect(paginatePayments(client, { status: "approved" }));
|
|
2669
|
+
* ```
|
|
2670
|
+
*
|
|
2671
|
+
* # Performance
|
|
2672
|
+
*
|
|
2673
|
+
* - **Streaming**: items are yielded as each page arrives — your downstream
|
|
2674
|
+
* work can start before all pages are fetched.
|
|
2675
|
+
* - **Bounded concurrency**: by default fetches one page at a time. Pass
|
|
2676
|
+
* `concurrency: 4` to prefetch up to 4 pages ahead (faster, more bandwidth).
|
|
2677
|
+
* - **Total cap**: pass `maxItems: 1000` to bail out early.
|
|
2678
|
+
*
|
|
2679
|
+
* # Edge cases handled
|
|
2680
|
+
*
|
|
2681
|
+
* - Empty pages (returns no items, terminates).
|
|
2682
|
+
* - Pages where total < expected (terminates correctly).
|
|
2683
|
+
* - Mid-iteration cancellation (caller breaks the for-await — no further fetches).
|
|
2684
|
+
* - Paging.total === 0 (terminates immediately).
|
|
2685
|
+
*/
|
|
2686
|
+
|
|
2687
|
+
interface PaginateOptions<TPage, TItem> {
|
|
2688
|
+
/** Extract the items array from a page. */
|
|
2689
|
+
extractItems: (page: TPage) => TItem[];
|
|
2690
|
+
/**
|
|
2691
|
+
* Extract the total count from a page. Used to know when to stop.
|
|
2692
|
+
* If not available, the iterator terminates when an empty page arrives.
|
|
2693
|
+
*/
|
|
2694
|
+
extractTotal?: (page: TPage) => number | undefined;
|
|
2695
|
+
/** Page size. Default 100 (MP's max for most endpoints). */
|
|
2696
|
+
pageSize?: number;
|
|
2697
|
+
/**
|
|
2698
|
+
* Stop after yielding `maxItems` total. Useful for "first N matching"
|
|
2699
|
+
* queries that would otherwise iterate the full result set.
|
|
2700
|
+
*/
|
|
2701
|
+
maxItems?: number;
|
|
2702
|
+
/**
|
|
2703
|
+
* Number of pages to prefetch concurrently. Default 1 (no prefetch).
|
|
2704
|
+
* Higher = lower wall-clock time but more concurrent MP requests.
|
|
2705
|
+
*/
|
|
2706
|
+
concurrency?: number;
|
|
2707
|
+
}
|
|
2708
|
+
/**
|
|
2709
|
+
* Generic paginator. Most callers use the typed convenience wrappers below.
|
|
2710
|
+
*
|
|
2711
|
+
* @param fetchPage Function that fetches page N given the offset.
|
|
2712
|
+
*/
|
|
2713
|
+
declare function paginate<TPage, TItem>(fetchPage: (offset: number, limit: number) => Promise<TPage>, opts: PaginateOptions<TPage, TItem>): AsyncGenerator<TItem, void, undefined>;
|
|
2714
|
+
/** Materialize an AsyncIterable into an array. Caller's responsibility to ensure it fits. */
|
|
2715
|
+
declare function collect<T>(iter: AsyncIterable<T>): Promise<T[]>;
|
|
2716
|
+
declare function paginatePayments(client: MercadoPagoClient, filter?: Parameters<MercadoPagoClient["searchPayments"]>[0], opts?: {
|
|
2717
|
+
pageSize?: number;
|
|
2718
|
+
maxItems?: number;
|
|
2719
|
+
concurrency?: number;
|
|
2720
|
+
}): AsyncGenerator<Payment, void, undefined>;
|
|
2721
|
+
declare function paginateSubscriptions(client: MercadoPagoClient, filter?: Parameters<MercadoPagoClient["searchPreapprovals"]>[0], opts?: {
|
|
2722
|
+
pageSize?: number;
|
|
2723
|
+
maxItems?: number;
|
|
2724
|
+
concurrency?: number;
|
|
2725
|
+
}): AsyncGenerator<Preapproval, void, undefined>;
|
|
2726
|
+
declare function paginateAccountMovements(client: MercadoPagoClient, filter?: {
|
|
2727
|
+
from?: string;
|
|
2728
|
+
to?: string;
|
|
2729
|
+
}, opts?: {
|
|
2730
|
+
pageSize?: number;
|
|
2731
|
+
maxItems?: number;
|
|
2732
|
+
concurrency?: number;
|
|
2733
|
+
}): AsyncGenerator<AccountMovement, void, undefined>;
|
|
2734
|
+
declare function paginateSettlements(client: MercadoPagoClient, filter?: {
|
|
2735
|
+
from?: string;
|
|
2736
|
+
to?: string;
|
|
2737
|
+
status?: string;
|
|
2738
|
+
}, opts?: {
|
|
2739
|
+
pageSize?: number;
|
|
2740
|
+
maxItems?: number;
|
|
2741
|
+
concurrency?: number;
|
|
2742
|
+
}): AsyncGenerator<Settlement, void, undefined>;
|
|
2743
|
+
declare function paginateMerchantOrders(client: MercadoPagoClient, filter?: Parameters<MercadoPagoClient["searchMerchantOrders"]>[0], opts?: {
|
|
2744
|
+
pageSize?: number;
|
|
2745
|
+
maxItems?: number;
|
|
2746
|
+
concurrency?: number;
|
|
2747
|
+
}): AsyncGenerator<MerchantOrder, void, undefined>;
|
|
2748
|
+
declare function paginateSubscriptionPlans(client: MercadoPagoClient, filter?: {
|
|
2749
|
+
status?: string;
|
|
2750
|
+
}, opts?: {
|
|
2751
|
+
pageSize?: number;
|
|
2752
|
+
maxItems?: number;
|
|
2753
|
+
concurrency?: number;
|
|
2754
|
+
}): AsyncGenerator<SubscriptionPlan, void, undefined>;
|
|
2755
|
+
declare function paginateSubscriptionPayments(client: MercadoPagoClient, preapprovalId: string, opts?: {
|
|
2756
|
+
pageSize?: number;
|
|
2757
|
+
maxItems?: number;
|
|
2758
|
+
concurrency?: number;
|
|
2759
|
+
}): AsyncGenerator<SubscriptionPayment, void, undefined>;
|
|
2760
|
+
|
|
2761
|
+
/**
|
|
2762
|
+
* Token bucket rate limiter — proactive client-side rate limiting.
|
|
2763
|
+
*
|
|
2764
|
+
* # Why proactive
|
|
2765
|
+
*
|
|
2766
|
+
* The current client honors `Retry-After` after a 429 (reactive). That's
|
|
2767
|
+
* good but suboptimal: every 429 still costs you a network round-trip, an
|
|
2768
|
+
* error log, and adds latency to the retry. Proactive rate limiting reads
|
|
2769
|
+
* MP's `x-rate-limit-remaining` header and slows down BEFORE the next 429.
|
|
2770
|
+
*
|
|
2771
|
+
* # The token bucket model
|
|
2772
|
+
*
|
|
2773
|
+
* - The bucket holds N tokens (the burst capacity).
|
|
2774
|
+
* - Tokens refill at R tokens/second (the steady-state rate).
|
|
2775
|
+
* - Each request consumes 1 token.
|
|
2776
|
+
* - When the bucket is empty, requests wait until a token is available.
|
|
2777
|
+
*
|
|
2778
|
+
* Example: capacity=20, refill=10/s means "burst 20 requests, then 10/s
|
|
2779
|
+
* sustained". Matches MP's typical limits (precise numbers vary by endpoint
|
|
2780
|
+
* and aren't publicly documented).
|
|
2781
|
+
*
|
|
2782
|
+
* # Per-host vs global
|
|
2783
|
+
*
|
|
2784
|
+
* Default: one bucket per `MercadoPagoClient`. Pass a SHARED bucket to
|
|
2785
|
+
* multiple clients in marketplace setups so they share the rate limit
|
|
2786
|
+
* (otherwise each per-seller client would think it has its own quota).
|
|
2787
|
+
*
|
|
2788
|
+
* # Adaptive learning
|
|
2789
|
+
*
|
|
2790
|
+
* The bucket auto-tunes from response headers: if MP says
|
|
2791
|
+
* `x-rate-limit-remaining: 5` and the bucket has 50 tokens, the bucket
|
|
2792
|
+
* is over-spending. The `learnFromHeaders` method updates the available
|
|
2793
|
+
* count to the lower of (current, MP's stated remaining).
|
|
2794
|
+
*/
|
|
2795
|
+
interface RateLimiterOptions {
|
|
2796
|
+
/** Bucket capacity (max burst). Default 50. */
|
|
2797
|
+
capacity?: number;
|
|
2798
|
+
/** Refill rate in tokens per second. Default 25. */
|
|
2799
|
+
refillPerSecond?: number;
|
|
2800
|
+
/**
|
|
2801
|
+
* If true, the limiter calls `learnFromHeaders` after every successful
|
|
2802
|
+
* request to keep its bucket in sync with MP's actual quota. Default true.
|
|
2803
|
+
*/
|
|
2804
|
+
adaptive?: boolean;
|
|
2805
|
+
/**
|
|
2806
|
+
* Hard cap on how long `acquire()` will wait. If the bucket can't refill
|
|
2807
|
+
* in this time, `acquire()` rejects with `RateLimitTimeoutError`.
|
|
2808
|
+
* Default 30s — anything longer is probably better handled as an error.
|
|
2809
|
+
*/
|
|
2810
|
+
acquireTimeoutMs?: number;
|
|
2811
|
+
/** Time provider (testing). Defaults to Date.now. */
|
|
2812
|
+
now?: () => number;
|
|
2813
|
+
}
|
|
2814
|
+
declare class RateLimitTimeoutError extends Error {
|
|
2815
|
+
readonly waitedMs: number;
|
|
2816
|
+
constructor(waitedMs: number);
|
|
2817
|
+
}
|
|
2818
|
+
declare class TokenBucketRateLimiter {
|
|
2819
|
+
private tokens;
|
|
2820
|
+
private lastRefill;
|
|
2821
|
+
private readonly capacity;
|
|
2822
|
+
private readonly refillPerSecond;
|
|
2823
|
+
private readonly adaptive;
|
|
2824
|
+
private readonly acquireTimeoutMs;
|
|
2825
|
+
private readonly now;
|
|
2826
|
+
constructor(opts?: RateLimiterOptions);
|
|
2827
|
+
/**
|
|
2828
|
+
* Acquire a token. Resolves immediately if tokens are available;
|
|
2829
|
+
* otherwise waits until one is. Rejects with `RateLimitTimeoutError`
|
|
2830
|
+
* if the wait exceeds `acquireTimeoutMs`.
|
|
2831
|
+
*/
|
|
2832
|
+
acquire(): Promise<void>;
|
|
2833
|
+
/**
|
|
2834
|
+
* Best-effort acquire: returns true if a token was available, false
|
|
2835
|
+
* otherwise. Doesn't wait. Useful for "non-blocking" code paths that
|
|
2836
|
+
* want to fall back to a cached response or queue the request elsewhere.
|
|
2837
|
+
*/
|
|
2838
|
+
tryAcquire(): boolean;
|
|
2839
|
+
/**
|
|
2840
|
+
* Adaptive learning hook — call after every API response with MP's
|
|
2841
|
+
* rate-limit headers to keep the bucket in sync with reality.
|
|
2842
|
+
*/
|
|
2843
|
+
learnFromHeaders(headers: {
|
|
2844
|
+
remaining: number | null;
|
|
2845
|
+
resetSeconds: number | null;
|
|
2846
|
+
}): void;
|
|
2847
|
+
/** Inspect the current bucket state. */
|
|
2848
|
+
getStats(): {
|
|
2849
|
+
tokens: number;
|
|
2850
|
+
capacity: number;
|
|
2851
|
+
refillPerSecond: number;
|
|
2852
|
+
};
|
|
2853
|
+
private refill;
|
|
2854
|
+
}
|
|
2855
|
+
|
|
2856
|
+
/**
|
|
2857
|
+
* Argentine issuer cuotas promotional catalog — embedded knowledge of which
|
|
2858
|
+
* banks/cards have "cuotas sin interés" (interest-free installment) deals
|
|
2859
|
+
* with which sellers, on which days.
|
|
2860
|
+
*
|
|
2861
|
+
* # Why embed this
|
|
2862
|
+
*
|
|
2863
|
+
* MP's `calculate_installments` API returns the CURRENT cuotas options for
|
|
2864
|
+
* a given (payment_method, amount, bin) tuple — but it doesn't tell the
|
|
2865
|
+
* agent which deals are GENERALLY available (e.g., "Naranja con Galicia, 6
|
|
2866
|
+
* cuotas sin interés todos los martes"). Devs surface that information to
|
|
2867
|
+
* buyers BEFORE checkout to drive conversion.
|
|
2868
|
+
*
|
|
2869
|
+
* This catalog is the AR-specific knowledge that turns the toolkit from
|
|
2870
|
+
* "MP API wrapper" into "MP integration with retail context".
|
|
2871
|
+
*
|
|
2872
|
+
* # Sources
|
|
2873
|
+
*
|
|
2874
|
+
* - Each issuer's published "Cuotas Simples" / "Ahora 12" page
|
|
2875
|
+
* - BCRA Comunicación A 7825 (financiamiento al consumo)
|
|
2876
|
+
* - Manually verified against Naranja, Galicia, Santander, Macro, BBVA, ICBC
|
|
2877
|
+
* Patagonia, Banco Nación, Banco Provincia, Banco Ciudad, Comafi, HSBC
|
|
2878
|
+
* public landing pages
|
|
2879
|
+
*
|
|
2880
|
+
* # Maintenance
|
|
2881
|
+
*
|
|
2882
|
+
* The promos schedule changes seasonally. Update this file quarterly + when
|
|
2883
|
+
* BCRA publishes a new "Ahora N" program. PRs welcomed.
|
|
2884
|
+
*
|
|
2885
|
+
* Last sync: 2026-Q2.
|
|
2886
|
+
*/
|
|
2887
|
+
interface CuotasPromo {
|
|
2888
|
+
/** Issuer name (matches `list_issuers` response). */
|
|
2889
|
+
issuer: string;
|
|
2890
|
+
/** Card brand (visa, master, amex, naranja, cabal, etc.). */
|
|
2891
|
+
paymentMethodId: string;
|
|
2892
|
+
/** Number of interest-free installments. */
|
|
2893
|
+
installments: number;
|
|
2894
|
+
/** Days of the week the promo applies. Empty = always. */
|
|
2895
|
+
daysOfWeek?: Array<"mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun">;
|
|
2896
|
+
/** ISO date when the promo starts (inclusive). */
|
|
2897
|
+
startDate?: string;
|
|
2898
|
+
/** ISO date when the promo expires (inclusive). */
|
|
2899
|
+
endDate?: string;
|
|
2900
|
+
/** Minimum purchase amount in ARS for the promo to apply. */
|
|
2901
|
+
minAmountArs?: number;
|
|
2902
|
+
/** Maximum monthly cap on the promo per cardholder. Optional. */
|
|
2903
|
+
maxAmountArs?: number;
|
|
2904
|
+
/** Free-form description shown to the buyer. ALWAYS surface verbatim. */
|
|
2905
|
+
description: string;
|
|
2906
|
+
/** Categories where the promo applies (per BCRA codes). Empty = any. */
|
|
2907
|
+
categories?: Array<"electronics" | "appliances" | "clothing" | "supermarket" | "travel" | "education" | "health" | "general">;
|
|
2908
|
+
}
|
|
2909
|
+
/**
|
|
2910
|
+
* The "Ahora 12 / 18 / 24 / 30" national program — recurring federal scheme
|
|
2911
|
+
* that subsidizes interest-free installments on essential categories.
|
|
2912
|
+
*
|
|
2913
|
+
* As of 2026-Q2: 3, 6, 12, 18, 24, 30 installment options on appliances,
|
|
2914
|
+
* electronics, clothing, books, school supplies, tires, eyewear, motorcycles,
|
|
2915
|
+
* national-tourism services. Not all categories qualify for all tiers.
|
|
2916
|
+
*/
|
|
2917
|
+
declare const AHORA_PROGRAM_PROMOS: CuotasPromo[];
|
|
2918
|
+
/**
|
|
2919
|
+
* Issuer-specific promos (running in addition to the Ahora program).
|
|
2920
|
+
*
|
|
2921
|
+
* Note: these change frequently. Check `lastVerified` before relying.
|
|
2922
|
+
*/
|
|
2923
|
+
declare const AR_ISSUER_PROMOS: CuotasPromo[];
|
|
2924
|
+
/**
|
|
2925
|
+
* Find applicable promos for a given context.
|
|
2926
|
+
*
|
|
2927
|
+
* Pure function — no I/O. Use to surface "cuotas sin interés" hints to the
|
|
2928
|
+
* buyer BEFORE they call `calculate_installments` (the API only returns
|
|
2929
|
+
* what's offered for the EXACT card, which the buyer hasn't entered yet).
|
|
2930
|
+
*
|
|
2931
|
+
* @example
|
|
2932
|
+
* ```ts
|
|
2933
|
+
* import { findApplicablePromos } from "@ar-agents/mercadopago";
|
|
2934
|
+
*
|
|
2935
|
+
* const promos = findApplicablePromos({
|
|
2936
|
+
* issuer: "Banco Galicia",
|
|
2937
|
+
* paymentMethodId: "visa",
|
|
2938
|
+
* amountArs: 50_000,
|
|
2939
|
+
* category: "supermarket",
|
|
2940
|
+
* date: new Date(), // optional, defaults to now
|
|
2941
|
+
* });
|
|
2942
|
+
* // → [{ installments: 12, description: "Galicia ... 12 cuotas sin interés ...", ... }]
|
|
2943
|
+
* ```
|
|
2944
|
+
*/
|
|
2945
|
+
declare function findApplicablePromos(args: {
|
|
2946
|
+
issuer?: string;
|
|
2947
|
+
paymentMethodId?: string;
|
|
2948
|
+
amountArs?: number;
|
|
2949
|
+
category?: NonNullable<CuotasPromo["categories"]>[number];
|
|
2950
|
+
date?: Date;
|
|
2951
|
+
/** Include the Ahora program in addition to issuer-specific. Default true. */
|
|
2952
|
+
includeAhoraProgram?: boolean;
|
|
2953
|
+
}): CuotasPromo[];
|
|
2244
2954
|
|
|
2245
2955
|
/**
|
|
2246
2956
|
* Pure helpers — no I/O, deterministic, fast. Importable directly from the
|
|
@@ -2307,4 +3017,4 @@ interface PaymentStatusExplanation {
|
|
|
2307
3017
|
*/
|
|
2308
3018
|
declare function explainPaymentStatus(payment: Payment): PaymentStatusExplanation;
|
|
2309
3019
|
|
|
2310
|
-
export { type AccountBalance, type AccountInfo, type AccountMovement, type AutoRecurring, type BankAccount, type CardToken, CircuitBreaker, type CircuitBreakerOptions, CircuitOpenError, type CircuitState, type CreateCardTokenParams, type CreateCustomerParams, type CreateOrderParams, type CreatePaymentParams, type CreatePointPaymentIntentParams, type CreatePosParams, type CreatePreapprovalParams, type CreatePreferenceParams, type CreateQrPaymentParams, type CreateRefundParams, type CreateStoreParams, type CreateSubscriptionPlanParams, type CreateWebhookParams, type CurrencyId, type Customer, type CustomerCard, type Dispute, type FrequencyType, type IdentificationType, type InstallmentOffer, type Issuer, type MarketplaceFeeRule, type MarketplaceParams, MercadoPagoAccountTypeMismatchError, MercadoPagoAuthError, MercadoPagoAuthorizeForbiddenError, MercadoPagoBackUrlInvalidError, MercadoPagoClient, type MercadoPagoClientOptions, MercadoPagoError, MercadoPagoOverloadedError, MercadoPagoPaymentRejectedError, MercadoPagoRateLimitError, MercadoPagoSelfPaymentError, MercadoPagoTimeoutError, type MercadoPagoToolsOptions, type MerchantOrder, type OAuthToken, type Order, type OrderItem, type OrderStatus, type ParsedWebhookEvent, type Payment, type PaymentMethod, type PaymentStatus, type PaymentStatusExplanation, type PaymentsSearchResult, type PointDevice, type PointPaymentIntent, type PointPaymentIntentState, type Pos, type Preapproval, type PreapprovalStatus, type Preference, type PreferenceItem, type QrOrder, type Refund, type SearchPaymentsParams, type Settlement, type SiteId, type Store, type SubscriptionPayment, type SubscriptionPlan, SubscriptionStateAdapter, TEST_CARDS_AR, TEST_PAYERS_AR, type TestCard, type ThreeDSInfo, type ThreeDSStatus, type WebhookBody, type WebhookConfig, type WebhookTopic, analyze3DS, buildAuthorizeUrl, buildTestCardScenario, classifyError, computeMarketplaceFee, exchangeCodeForToken, expirationTimeMs, explainPaymentStatus, isExpiringSoon, mercadoPagoTools, parseWebhookEvent, refreshAccessToken, verifyWebhookSignature };
|
|
3020
|
+
export { AHORA_PROGRAM_PROMOS, AR_ISSUER_PROMOS, type AccountBalance, type AccountInfo, type AccountMovement, type AuditEntry, type AuditLogAdapter, AuditLogger, type AuditOperation, type AutoRecurring, type BankAccount, type CardToken, CircuitBreaker, type CircuitBreakerOptions, CircuitOpenError, type CircuitState, type CreateCardTokenParams, type CreateCustomerParams, type CreateOrderParams, type CreatePaymentParams, type CreatePointPaymentIntentParams, type CreatePosParams, type CreatePreapprovalParams, type CreatePreferenceParams, type CreateQrPaymentParams, type CreateRefundParams, type CreateStoreParams, type CreateSubscriptionPlanParams, type CreateWebhookParams, type CuotasPromo, type CurrencyId, type Customer, type CustomerCard, type DedupResult, type Dispute, type FrequencyType, IdempotencyCache, type IdentificationType, InMemoryAuditLog, type InstallmentOffer, type Issuer, type MarketplaceFeeRule, type MarketplaceParams, MercadoPagoAccountTypeMismatchError, MercadoPagoAuthError, MercadoPagoAuthorizeForbiddenError, MercadoPagoBackUrlInvalidError, MercadoPagoClient, type MercadoPagoClientOptions, MercadoPagoError, MercadoPagoOverloadedError, MercadoPagoPaymentRejectedError, MercadoPagoRateLimitError, MercadoPagoSelfPaymentError, MercadoPagoTimeoutError, type MercadoPagoToolsOptions, type MerchantOrder, type OAuthToken, type Order, type OrderItem, type OrderStatus, type PaginateOptions, type ParsedWebhookEvent, type Payment, type PaymentMethod, type PaymentStatus, type PaymentStatusExplanation, type PaymentsSearchResult, type PointDevice, type PointPaymentIntent, type PointPaymentIntentState, type Pos, type Preapproval, type PreapprovalStatus, type Preference, type PreferenceItem, type QrOrder, RateLimitTimeoutError, type RateLimiterOptions, type Refund, type SearchPaymentsParams, type Settlement, type SiteId, type Store, type SubscriptionPayment, type SubscriptionPlan, SubscriptionStateAdapter, TEST_CARDS_AR, TEST_PAYERS_AR, type TestCard, type ThreeDSInfo, type ThreeDSStatus, TokenBucketRateLimiter, type WebhookBody, type WebhookConfig, WebhookDedup, type WebhookDedupOptions, type WebhookTopic, analyze3DS, buildAuthorizeUrl, buildTestCardScenario, classifyError, collect, computeMarketplaceFee, confirmChallengeAndPoll, exchangeCodeForToken, expirationTimeMs, explainPaymentStatus, findApplicablePromos, isExpiringSoon, mercadoPagoTools, paginate, paginateAccountMovements, paginateMerchantOrders, paginatePayments, paginateSettlements, paginateSubscriptionPayments, paginateSubscriptionPlans, paginateSubscriptions, parseWebhookEvent, refreshAccessToken, verifyWebhookSignature };
|