@stacksjs/payments 0.75.223 → 0.75.225

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.
@@ -89,6 +89,7 @@ export declare interface CardPresentPaymentIntentInput {
89
89
  metadata?: Record<string, string>
90
90
  onBehalfOf?: string
91
91
  transferDestination?: string
92
+ applicationFeeAmount?: number
92
93
  captureMethod?: 'automatic' | 'manual'
93
94
  statementDescriptorSuffix?: string
94
95
  }
@@ -106,7 +107,7 @@ export declare interface StripeTerminal {
106
107
  processPaymentIntent: (readerId: string, paymentIntentId: string, idempotencyKey?: string) => Promise<TerminalReader>
107
108
  cancelReaderAction: (readerId: string) => Promise<TerminalReader>
108
109
  presentPaymentMethod: (readerId: string, card?: { number?: string, type?: 'card_present' | 'interac_present' }) => Promise<TerminalReader>
109
- refund: (input: { paymentIntent: string, amount?: number, reverseTransfer?: boolean, metadata?: Record<string, string>, reason?: 'duplicate' | 'fraudulent' | 'requested_by_customer' }, idempotencyKey: string) => Promise<any>
110
+ refund: (input: { paymentIntent: string, amount?: number, reverseTransfer?: boolean, refundApplicationFee?: boolean, metadata?: Record<string, string>, reason?: 'duplicate' | 'fraudulent' | 'requested_by_customer' }, idempotencyKey: string) => Promise<any>
110
111
  }
111
112
  export declare interface TerminalChargeOutcome {
112
113
  state: TerminalChargeState
package/dist/terminal.js CHANGED
@@ -1 +1 @@
1
- export class StripeApiError extends Error{status;type;code;declineCode;param;constructor(message,status,error={}){super(message);this.status=status;this.name="StripeApiError";this.type=error.type||(status===0?"api_connection_error":"api_error");this.code=error.code??null;this.declineCode=error.decline_code??null;this.param=error.param??null}get definitive(){return["invalid_request_error","card_error","authentication_error","permission_error"].includes(this.type)}}export const STRIPE_TERMINAL_API_VERSION="2026-09-30.endive";export function stripeFormEncode(params){const pairs=[],add=(key,value)=>{if(value===null||value===void 0)return;if(Array.isArray(value)){value.forEach((item,index)=>add(`${key}[${index}]`,item));return}if(typeof value==="object"){for(const[child,inner]of Object.entries(value))add(`${key}[${child}]`,inner);return}pairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)};for(const[key,value]of Object.entries(params))add(key,value);return pairs.join("&")}export function stripeRest(options){const base=(options.apiBase||"https://api.stripe.com").replace(/\/$/,""),doFetch=options.fetch??fetch;return{async request(method,path,params={},requestOptions={}){const body=stripeFormEncode(params),url=method==="POST"||!body?`${base}${path}`:`${base}${path}?${body}`,headers={Authorization:`Bearer ${options.secretKey}`,Accept:"application/json"};if(method==="POST")headers["Content-Type"]="application/x-www-form-urlencoded";const version=options.apiVersion===void 0?STRIPE_TERMINAL_API_VERSION:options.apiVersion;if(version)headers["Stripe-Version"]=version;if(options.stripeAccount)headers["Stripe-Account"]=options.stripeAccount;if(requestOptions.idempotencyKey)headers["Idempotency-Key"]=requestOptions.idempotencyKey;let res;try{res=await doFetch(url,{method,headers,body:method==="POST"?body:void 0,signal:AbortSignal.timeout(options.timeoutMs??30000)})}catch(error){throw new StripeApiError(`Could not reach Stripe: ${error instanceof Error?error.message:String(error)}`,0)}const text=await res.text();let json=null;try{json=text?JSON.parse(text):null}catch{json=null}if(!res.ok){const error=json?.error&&typeof json.error==="object"?json.error:{};throw new StripeApiError(typeof error.message==="string"&&error.message?error.message:`Stripe answered ${res.status}`,res.status,error)}return json}}}const path=(value)=>encodeURIComponent(value);export function stripeTerminal(options){const api=stripeRest(options);return{connectionToken:(location)=>api.request("POST","/v1/terminal/connection_tokens",{location}),createLocation:(input,idempotencyKey)=>api.request("POST","/v1/terminal/locations",{display_name:input.displayName,address:{...input.address},metadata:input.metadata},{idempotencyKey}),retrieveLocation:(id)=>api.request("GET",`/v1/terminal/locations/${path(id)}`),registerReader:(input)=>api.request("POST","/v1/terminal/readers",{registration_code:input.registrationCode,label:input.label,location:input.location,metadata:input.metadata}),retrieveReader:(id)=>api.request("GET",`/v1/terminal/readers/${path(id)}`),async listReaders(filter={}){const page=await api.request("GET","/v1/terminal/readers",{location:filter.location,limit:filter.limit??100});return Array.isArray(page?.data)?page.data:[]},deleteReader:(id)=>api.request("DELETE",`/v1/terminal/readers/${path(id)}`),createPaymentIntent:(input,idempotencyKey)=>api.request("POST","/v1/payment_intents",{amount:input.amount,currency:input.currency.toLowerCase(),allowed_payment_method_types:["card_present"],capture_method:input.captureMethod??"automatic",description:input.description,metadata:input.metadata,on_behalf_of:input.onBehalfOf,transfer_data:input.transferDestination?{destination:input.transferDestination}:void 0,statement_descriptor_suffix:input.statementDescriptorSuffix},{idempotencyKey}),retrievePaymentIntent:(id)=>api.request("GET",`/v1/payment_intents/${path(id)}`,{expand:["latest_charge"]}),cancelPaymentIntent:(id)=>api.request("POST",`/v1/payment_intents/${path(id)}/cancel`),processPaymentIntent:(readerId,paymentIntentId,idempotencyKey)=>api.request("POST",`/v1/terminal/readers/${path(readerId)}/process_payment_intent`,{payment_intent:paymentIntentId},{idempotencyKey}),cancelReaderAction:(readerId)=>api.request("POST",`/v1/terminal/readers/${path(readerId)}/cancel_action`),presentPaymentMethod:(readerId,card={})=>api.request("POST",`/v1/test_helpers/terminal/readers/${path(readerId)}/present_payment_method`,{type:card.type,card_present:card.number?{number:card.number}:void 0}),refund:(input,idempotencyKey)=>api.request("POST","/v1/refunds",{payment_intent:input.paymentIntent,amount:input.amount,reverse_transfer:input.reverseTransfer,reason:input.reason,metadata:input.metadata},{idempotencyKey})}}export function terminalChargeState(paymentIntent,reader){const status=paymentIntent?.status;if(status==="succeeded"||status==="requires_capture")return{state:"succeeded",failureCode:null,failureMessage:null};if(status==="canceled")return{state:"canceled",failureCode:null,failureMessage:null};const action=reader?.action,forThis=!!action&&action.type==="process_payment_intent"&&(!paymentIntent?.id||action.process_payment_intent?.payment_intent===paymentIntent.id);if(forThis&&action.status==="failed")return{state:"failed",failureCode:action.failure_code||"reader_action_failed",failureMessage:action.failure_message||null};if(forThis&&action.status==="in_progress")return{state:"waiting",failureCode:null,failureMessage:null};const error=paymentIntent?.last_payment_error;if(status==="requires_payment_method"&&error)return{state:"failed",failureCode:error.decline_code||error.code||"card_declined",failureMessage:error.message||null};return{state:"waiting",failureCode:null,failureMessage:null}}export function cardPresentDetails(chargeOrIntent){const charge=chargeOrIntent?.object==="payment_intent"?typeof chargeOrIntent.latest_charge==="object"&&chargeOrIntent.latest_charge?chargeOrIntent.latest_charge:chargeOrIntent.charges?.data?.[0]:chargeOrIntent,card=charge?.payment_method_details?.card_present??charge?.payment_method_details?.interac_present;if(!card)return null;const receipt=card.receipt??{},text=(value)=>typeof value==="string"&&value?value:null;return{brand:text(card.brand),last4:text(card.last4),funding:text(card.funding),readMethod:text(card.read_method),applicationName:text(receipt.application_preferred_name),applicationId:text(receipt.dedicated_file_name),authorizationCode:text(charge.authorization_code??receipt.authorization_code),authorizationResponseCode:text(receipt.authorization_response_code),accountType:text(receipt.account_type),cardholderVerification:text(receipt.cardholder_verification_method)}}export function latestChargeId(paymentIntent){const charge=paymentIntent?.latest_charge;if(typeof charge==="string"&&charge)return charge;if(charge&&typeof charge.id==="string")return charge.id;const legacy=paymentIntent?.charges?.data?.[0]?.id;return typeof legacy==="string"?legacy:null}export const SIMULATED_READER_CODES=["simulated-wpe","simulated-s700","simulated-s710","simulated-v660p","simulated-wp3"];export function isTestKey(secretKey){return typeof secretKey==="string"&&/^(sk|rk)_test_/.test(secretKey)}
1
+ export class StripeApiError extends Error{status;type;code;declineCode;param;constructor(message,status,error={}){super(message);this.status=status;this.name="StripeApiError";this.type=error.type||(status===0?"api_connection_error":"api_error");this.code=error.code??null;this.declineCode=error.decline_code??null;this.param=error.param??null}get definitive(){return["invalid_request_error","card_error","authentication_error","permission_error"].includes(this.type)}}export const STRIPE_TERMINAL_API_VERSION="2026-09-30.endive";export function stripeFormEncode(params){const pairs=[],add=(key,value)=>{if(value===null||value===void 0)return;if(Array.isArray(value)){value.forEach((item,index)=>add(`${key}[${index}]`,item));return}if(typeof value==="object"){for(const[child,inner]of Object.entries(value))add(`${key}[${child}]`,inner);return}pairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)};for(const[key,value]of Object.entries(params))add(key,value);return pairs.join("&")}export function stripeRest(options){const base=(options.apiBase||"https://api.stripe.com").replace(/\/$/,""),doFetch=options.fetch??fetch;return{async request(method,path,params={},requestOptions={}){const body=stripeFormEncode(params),url=method==="POST"||!body?`${base}${path}`:`${base}${path}?${body}`,headers={Authorization:`Bearer ${options.secretKey}`,Accept:"application/json"};if(method==="POST")headers["Content-Type"]="application/x-www-form-urlencoded";const version=options.apiVersion===void 0?STRIPE_TERMINAL_API_VERSION:options.apiVersion;if(version)headers["Stripe-Version"]=version;if(options.stripeAccount)headers["Stripe-Account"]=options.stripeAccount;if(requestOptions.idempotencyKey)headers["Idempotency-Key"]=requestOptions.idempotencyKey;let res;try{res=await doFetch(url,{method,headers,body:method==="POST"?body:void 0,signal:AbortSignal.timeout(options.timeoutMs??30000)})}catch(error){throw new StripeApiError(`Could not reach Stripe: ${error instanceof Error?error.message:String(error)}`,0)}const text=await res.text();let json=null;try{json=text?JSON.parse(text):null}catch{json=null}if(!res.ok){const error=json?.error&&typeof json.error==="object"?json.error:{};throw new StripeApiError(typeof error.message==="string"&&error.message?error.message:`Stripe answered ${res.status}`,res.status,error)}return json}}}const path=(value)=>encodeURIComponent(value);export function stripeTerminal(options){const api=stripeRest(options);return{connectionToken:(location)=>api.request("POST","/v1/terminal/connection_tokens",{location}),createLocation:(input,idempotencyKey)=>api.request("POST","/v1/terminal/locations",{display_name:input.displayName,address:{...input.address},metadata:input.metadata},{idempotencyKey}),retrieveLocation:(id)=>api.request("GET",`/v1/terminal/locations/${path(id)}`),registerReader:(input)=>api.request("POST","/v1/terminal/readers",{registration_code:input.registrationCode,label:input.label,location:input.location,metadata:input.metadata}),retrieveReader:(id)=>api.request("GET",`/v1/terminal/readers/${path(id)}`),async listReaders(filter={}){const page=await api.request("GET","/v1/terminal/readers",{location:filter.location,limit:filter.limit??100});return Array.isArray(page?.data)?page.data:[]},deleteReader:(id)=>api.request("DELETE",`/v1/terminal/readers/${path(id)}`),createPaymentIntent:(input,idempotencyKey)=>api.request("POST","/v1/payment_intents",{amount:input.amount,currency:input.currency.toLowerCase(),allowed_payment_method_types:["card_present"],capture_method:input.captureMethod??"automatic",description:input.description,metadata:input.metadata,on_behalf_of:input.onBehalfOf,transfer_data:input.transferDestination?{destination:input.transferDestination}:void 0,application_fee_amount:input.applicationFeeAmount&&input.applicationFeeAmount>0?input.applicationFeeAmount:void 0,statement_descriptor_suffix:input.statementDescriptorSuffix},{idempotencyKey}),retrievePaymentIntent:(id)=>api.request("GET",`/v1/payment_intents/${path(id)}`,{expand:["latest_charge"]}),cancelPaymentIntent:(id)=>api.request("POST",`/v1/payment_intents/${path(id)}/cancel`),processPaymentIntent:(readerId,paymentIntentId,idempotencyKey)=>api.request("POST",`/v1/terminal/readers/${path(readerId)}/process_payment_intent`,{payment_intent:paymentIntentId},{idempotencyKey}),cancelReaderAction:(readerId)=>api.request("POST",`/v1/terminal/readers/${path(readerId)}/cancel_action`),presentPaymentMethod:(readerId,card={})=>api.request("POST",`/v1/test_helpers/terminal/readers/${path(readerId)}/present_payment_method`,{type:card.type,card_present:card.number?{number:card.number}:void 0}),refund:(input,idempotencyKey)=>api.request("POST","/v1/refunds",{payment_intent:input.paymentIntent,amount:input.amount,reverse_transfer:input.reverseTransfer,refund_application_fee:input.refundApplicationFee,reason:input.reason,metadata:input.metadata},{idempotencyKey})}}export function terminalChargeState(paymentIntent,reader){const status=paymentIntent?.status;if(status==="succeeded"||status==="requires_capture")return{state:"succeeded",failureCode:null,failureMessage:null};if(status==="canceled")return{state:"canceled",failureCode:null,failureMessage:null};const action=reader?.action,forThis=!!action&&action.type==="process_payment_intent"&&(!paymentIntent?.id||action.process_payment_intent?.payment_intent===paymentIntent.id);if(forThis&&action.status==="failed")return{state:"failed",failureCode:action.failure_code||"reader_action_failed",failureMessage:action.failure_message||null};if(forThis&&action.status==="in_progress")return{state:"waiting",failureCode:null,failureMessage:null};const error=paymentIntent?.last_payment_error;if(status==="requires_payment_method"&&error)return{state:"failed",failureCode:error.decline_code||error.code||"card_declined",failureMessage:error.message||null};return{state:"waiting",failureCode:null,failureMessage:null}}export function cardPresentDetails(chargeOrIntent){const charge=chargeOrIntent?.object==="payment_intent"?typeof chargeOrIntent.latest_charge==="object"&&chargeOrIntent.latest_charge?chargeOrIntent.latest_charge:chargeOrIntent.charges?.data?.[0]:chargeOrIntent,card=charge?.payment_method_details?.card_present??charge?.payment_method_details?.interac_present;if(!card)return null;const receipt=card.receipt??{},text=(value)=>typeof value==="string"&&value?value:null;return{brand:text(card.brand),last4:text(card.last4),funding:text(card.funding),readMethod:text(card.read_method),applicationName:text(receipt.application_preferred_name),applicationId:text(receipt.dedicated_file_name),authorizationCode:text(charge.authorization_code??receipt.authorization_code),authorizationResponseCode:text(receipt.authorization_response_code),accountType:text(receipt.account_type),cardholderVerification:text(receipt.cardholder_verification_method)}}export function latestChargeId(paymentIntent){const charge=paymentIntent?.latest_charge;if(typeof charge==="string"&&charge)return charge;if(charge&&typeof charge.id==="string")return charge.id;const legacy=paymentIntent?.charges?.data?.[0]?.id;return typeof legacy==="string"?legacy:null}export const SIMULATED_READER_CODES=["simulated-wpe","simulated-s700","simulated-s710","simulated-v660p","simulated-wp3"];export function isTestKey(secretKey){return typeof secretKey==="string"&&/^(sk|rk)_test_/.test(secretKey)}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/payments",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.75.223",
5
+ "version": "0.75.225",
6
6
  "description": "The Stacks payments package. Currently supporting Stripe.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -60,12 +60,12 @@
60
60
  "prepublishOnly": "bun run build"
61
61
  },
62
62
  "dependencies": {
63
- "@stacksjs/config": "0.75.223",
64
- "@stacksjs/database": "0.75.223",
65
- "@stacksjs/error-handling": "0.75.223",
66
- "@stacksjs/logging": "0.75.223",
67
- "@stacksjs/orm": "0.75.223",
68
- "@stacksjs/types": "0.75.223"
63
+ "@stacksjs/config": "0.75.225",
64
+ "@stacksjs/database": "0.75.225",
65
+ "@stacksjs/error-handling": "0.75.225",
66
+ "@stacksjs/logging": "0.75.225",
67
+ "@stacksjs/orm": "0.75.225",
68
+ "@stacksjs/types": "0.75.225"
69
69
  },
70
70
  "peerDependencies": {
71
71
  "@stripe/stripe-js": "^10.0.0",
@@ -80,7 +80,7 @@
80
80
  }
81
81
  },
82
82
  "devDependencies": {
83
- "@stacksjs/utils": "0.75.223",
83
+ "@stacksjs/utils": "0.75.225",
84
84
  "@stripe/stripe-js": "^10.0.0",
85
85
  "better-dx": "^0.2.24",
86
86
  "stripe": "23.0.0"