├── src ├── index.ts ├── enums │ ├── index.ts │ └── apiEnums.ts ├── types │ ├── index.ts │ ├── traditional │ │ ├── complete-sale-response.ts │ │ ├── revoke-token-response.ts │ │ ├── send-invoice-response.ts │ │ ├── set-tax-table-response.ts │ │ ├── set-user-notes-response.ts │ │ ├── revise-my-messages-response.ts │ │ ├── add-order-response.ts │ │ ├── delete-my-messages-response.ts │ │ ├── respond-to-feedback-response.ts │ │ ├── set-user-preferences-response.ts │ │ ├── add-member-message-r-t-q-response.ts │ │ ├── revise-my-messages-folders-response.ts │ │ ├── set-message-preferences-response.ts │ │ ├── add-to-watch-list-response.ts │ │ ├── end-fixed-price-item-response.ts │ │ ├── set-notification-preferences-response.ts │ │ ├── set-shipping-discount-profiles-response.ts │ │ ├── fetch-token-response.ts │ │ ├── remove-from-watch-list-response.ts │ │ ├── add-member-message-a-a-q-to-partner-response.ts │ │ ├── add-second-chance-item-response.ts │ │ ├── verify-add-second-chance-item-response.ts │ │ ├── get-message-preferences-response.ts │ │ ├── set-store-categories-response.ts │ │ ├── respond-to-best-offer-response.ts │ │ ├── ve-r-o-report-items-response.ts │ │ ├── get-tax-table-response.ts │ │ ├── add-member-messages-a-a-q-to-bidder-response.ts │ │ ├── add-to-item-description-response.ts │ │ ├── get-user-contact-details-response.ts │ │ ├── get-token-status-response.ts │ │ ├── revise-inventory-status-response.ts │ │ ├── end-items-response.ts │ │ ├── verify-add-fixed-price-item-response.ts │ │ ├── upload-site-hosted-pictures-response.ts │ │ ├── get-description-templates-response.ts │ │ ├── verify-relist-item-response.ts │ │ ├── verify-add-item-response.ts │ │ ├── add-item-response.ts │ │ ├── relist-item-response.ts │ │ ├── revise-item-response.ts │ │ ├── get-categories-response.ts │ │ ├── add-fixed-price-item-response.ts │ │ ├── get-store-response.ts │ │ ├── relist-fixed-price-item-response.ts │ │ ├── revise-fixed-price-item-response.ts │ │ ├── get-ve-r-o-report-status-response.ts │ │ ├── get-ve-r-o-reason-code-details-response.ts │ │ ├── add-items-response.ts │ │ ├── place-offer-response.ts │ │ ├── get-ad-format-leads-response.ts │ │ ├── get-member-messages-response.ts │ │ ├── get-my-messages-response.ts │ │ ├── get-items-awaiting-feedback-response.ts │ │ ├── get-best-offers-response.ts │ │ ├── get-shipping-discount-profiles-response.ts │ │ ├── index.ts │ │ ├── get-user-preferences-response.ts │ │ ├── get-feedback-response.ts │ │ └── get-all-bidders-response.ts │ ├── apiTypes.ts │ └── restful │ │ └── specs │ │ ├── cancellation_oas3.ts │ │ └── case_oas3.ts ├── api │ ├── traditional │ │ ├── merchandising │ │ │ └── index.ts │ │ ├── finding │ │ │ └── index.ts │ │ ├── clientAlerts │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── shopping │ │ │ └── index.ts │ │ └── trading │ │ │ └── index.ts │ ├── restful │ │ ├── developer │ │ │ ├── index.ts │ │ │ ├── keyManagement │ │ │ │ └── index.ts │ │ │ └── analytics │ │ │ │ └── index.ts │ │ ├── postOrder │ │ │ ├── index.ts │ │ │ ├── cancellation │ │ │ │ └── index.ts │ │ │ ├── case │ │ │ │ └── index.ts │ │ │ └── inquiry │ │ │ │ └── index.ts │ │ ├── buy │ │ │ ├── index.ts │ │ │ ├── offer │ │ │ │ └── index.ts │ │ │ ├── marketing │ │ │ │ └── index.ts │ │ │ ├── marketplaceInsights │ │ │ │ └── index.ts │ │ │ ├── feed │ │ │ │ └── index.ts │ │ │ └── deal │ │ │ │ └── index.ts │ │ ├── commerce │ │ │ ├── index.ts │ │ │ ├── identity │ │ │ │ └── index.ts │ │ │ ├── translation │ │ │ │ └── index.ts │ │ │ ├── media │ │ │ │ └── index.ts │ │ │ ├── charity │ │ │ │ └── index.ts │ │ │ └── catalog │ │ │ │ └── index.ts │ │ └── sell │ │ │ ├── listing │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── negotiation │ │ │ └── index.ts │ │ │ ├── recommendation │ │ │ └── index.ts │ │ │ ├── account │ │ │ └── v2.ts │ │ │ ├── compliance │ │ │ └── index.ts │ │ │ ├── analytics │ │ │ └── index.ts │ │ │ ├── logistics │ │ │ └── index.ts │ │ │ └── finances │ │ │ └── index.ts │ ├── base.ts │ ├── index.ts │ ├── apiFactory.ts │ └── digitalSignature.ts ├── nanoevents.ts ├── auth │ ├── index.ts │ └── authNAuth.ts └── request.ts ├── examples ├── traditional │ ├── upload_ok.png │ ├── upload_bad_quality.jpg │ ├── merchandising.getMostWatchedItems.ts │ ├── trading.GetAccount.ts │ ├── trading.GeteBayOfficialTime.ts │ ├── trading.GetMultipleItems.ts │ ├── shopping.GetUserProfile.ts │ ├── trading.GetMyMessages.ts │ ├── shopping.GetSingleItem.ts │ ├── finding.findItemsAdvanced.ts │ ├── trading.GetMyeBaySelling.ts │ ├── clientAlerts.GetPublicAlerts.ts │ ├── authNAuth.ts │ └── trading.UploadSiteHostedPictures.ts ├── restful │ ├── buy │ │ ├── browse.getShoppingCart.ts │ │ ├── items.getItem.ts │ │ ├── browse.search.ts │ │ └── marketing.getAlsoBoughtProducts.ts │ ├── sell │ │ ├── account.getPrivileges.ts │ │ ├── finances.ts │ │ ├── fullfillment.getOrder.ts │ │ ├── metadata.getItemConditionPolicies.ts │ │ └── getOrders.ts │ ├── postOrder │ │ ├── return.getReturn.ts │ │ └── inquiry.getInquiry.ts │ ├── developer │ │ ├── analytics.ts │ │ └── keyManagement.ts │ └── authFlow.ts └── README.md ├── .mocharc.json ├── .gitignore ├── .travis.yml ├── SUMMARY.md ├── tsconfig.cjs.json ├── scripts └── update-readme-release.cjs ├── .npmignore ├── test └── api │ ├── jsonfile.ts │ ├── restful │ ├── developer │ │ └── index.ts │ ├── postOrder │ │ └── index.ts │ ├── buy │ │ └── index.ts │ ├── commerce │ │ └── index.ts │ ├── sell │ │ └── index.ts │ └── oas.spec.ts │ ├── factory.spec.ts │ ├── errors │ ├── errors.json │ └── errors.spec.ts │ ├── digitalSignature.spec.ts │ └── authNAuth.spec.ts ├── .versionrc.json ├── tsconfig.json ├── .github ├── stale.yml └── ISSUE_TEMPLATE │ └── bug_report.md ├── CONTRIBUTING.md ├── tslint.json ├── LICENSE ├── rollup.config.js └── specs └── cancellation_oas3.json /src/index.ts: -------------------------------------------------------------------------------- 1 | import eBayApi from './eBayApi.js'; 2 | 3 | export = eBayApi; -------------------------------------------------------------------------------- /src/enums/index.ts: -------------------------------------------------------------------------------- 1 | export * from './apiEnums.js'; 2 | export * from './restfulEnums.js'; 3 | -------------------------------------------------------------------------------- /examples/traditional/upload_ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hendt/ebay-api/HEAD/examples/traditional/upload_ok.png -------------------------------------------------------------------------------- /.mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extension": [ 3 | "ts" 4 | ], 5 | "spec": "test/**/*.spec.ts", 6 | "loader": "ts-node/esm" 7 | } -------------------------------------------------------------------------------- /examples/traditional/upload_bad_quality.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hendt/ebay-api/HEAD/examples/traditional/upload_bad_quality.jpg -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | dist 4 | *.sublime* 5 | *.log 6 | *.iml 7 | .idea 8 | ebay-api.iml 9 | .nyc_output 10 | coverage -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 14 4 | before_install: 5 | - npm install -g codecov 6 | script: 7 | - npm run report:summary 8 | - codecov -------------------------------------------------------------------------------- /src/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './apiTypes.js'; 2 | export * from './restfulTypes.js'; 3 | export * from './traditonalTypes.js'; 4 | export * from './traditional/index.js'; -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [eBay TypeScript/JavaScript API for Browser and Node](README.md) 4 | * [eBay API on Github](https://github.com/hendt/ebay-api) 5 | 6 | -------------------------------------------------------------------------------- /src/api/traditional/merchandising/index.ts: -------------------------------------------------------------------------------- 1 | enum calls { 2 | getMostWatchedItems, 3 | getRelatedCategoryItems, 4 | getSimilarItems, 5 | getVersion 6 | } 7 | 8 | export default calls; 9 | -------------------------------------------------------------------------------- /tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "ES2020", 5 | "outDir": "./lib", 6 | "moduleResolution": "node" 7 | }, 8 | "exclude": [], 9 | "extends": "./tsconfig.json" 10 | } 11 | -------------------------------------------------------------------------------- /src/types/traditional/complete-sale-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/CompleteSale.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface CompleteSaleResponse extends StandardOutputFields { 5 | } 6 | -------------------------------------------------------------------------------- /src/types/traditional/revoke-token-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/RevokeToken.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface RevokeTokenResponse extends StandardOutputFields { 5 | } 6 | -------------------------------------------------------------------------------- /src/types/traditional/send-invoice-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/SendInvoice.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface SendInvoiceResponse extends StandardOutputFields { 5 | } 6 | -------------------------------------------------------------------------------- /src/types/traditional/set-tax-table-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/SetTaxTable.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface SetTaxTableResponse extends StandardOutputFields { 5 | } 6 | -------------------------------------------------------------------------------- /src/types/traditional/set-user-notes-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/SetUserNotes.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface SetUserNotesResponse extends StandardOutputFields { 5 | } 6 | -------------------------------------------------------------------------------- /src/types/traditional/revise-my-messages-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/ReviseMyMessages.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface ReviseMyMessagesResponse extends StandardOutputFields {} 5 | -------------------------------------------------------------------------------- /src/types/traditional/add-order-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/AddOrder.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface AddOrderResponse extends StandardOutputFields { 5 | OrderID: string; 6 | } 7 | -------------------------------------------------------------------------------- /src/types/traditional/delete-my-messages-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/DeleteMyMessages.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface DeleteMyMessagesResponse extends StandardOutputFields { 5 | } 6 | -------------------------------------------------------------------------------- /src/types/traditional/respond-to-feedback-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/RespondToFeedback.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface RespondToFeedbackResponse extends StandardOutputFields { 5 | } 6 | -------------------------------------------------------------------------------- /src/types/traditional/set-user-preferences-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/SetUserPreferences.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface SetUserPreferencesResponse extends StandardOutputFields { 5 | } 6 | -------------------------------------------------------------------------------- /src/types/traditional/add-member-message-r-t-q-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/AddMemberMessageRTQ.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface AddMemberMessageRTQResponse extends StandardOutputFields { 5 | } 6 | -------------------------------------------------------------------------------- /src/types/traditional/revise-my-messages-folders-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/ReviseMyMessagesFolders.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface ReviseMyMessagesFoldersResponse extends StandardOutputFields {} 5 | -------------------------------------------------------------------------------- /src/types/traditional/set-message-preferences-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/SetMessagePreferences.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface SetMessagePreferencesResponse extends StandardOutputFields { 5 | } 6 | -------------------------------------------------------------------------------- /examples/restful/buy/browse.getShoppingCart.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | eBay.buy.browse.getShoppingCart().then(cart => { 7 | console.log(cart); 8 | }).catch(e => { 9 | console.log(e); 10 | }); 11 | -------------------------------------------------------------------------------- /src/types/traditional/add-to-watch-list-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/AddToWatchList.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface AddToWatchListResponse extends StandardOutputFields { 5 | WatchListMaximum: number; 6 | } 7 | -------------------------------------------------------------------------------- /src/types/traditional/end-fixed-price-item-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/EndFixedPriceItem.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface EndFixedPriceItemResponse extends StandardOutputFields { 5 | SKU?: string; 6 | } 7 | -------------------------------------------------------------------------------- /src/types/traditional/set-notification-preferences-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/SetNotificationPreferences.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface SetNotificationPreferencesResponse extends StandardOutputFields { 5 | } 6 | -------------------------------------------------------------------------------- /src/api/restful/developer/index.ts: -------------------------------------------------------------------------------- 1 | import Analytics from './analytics/index.js'; 2 | import KeyManagement from './keyManagement/index.js'; 3 | 4 | export type Developer = { 5 | analytics: Analytics, 6 | keyManagement: KeyManagement 7 | }; 8 | 9 | export { 10 | Analytics, 11 | KeyManagement 12 | }; 13 | -------------------------------------------------------------------------------- /src/types/traditional/set-shipping-discount-profiles-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/SetShippingDiscountProfiles.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface SetShippingDiscountProfilesResponse extends StandardOutputFields { 5 | } 6 | -------------------------------------------------------------------------------- /src/types/traditional/fetch-token-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/FetchToken.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface FetchTokenResponse extends StandardOutputFields { 5 | HardExpirationTime: string; 6 | RESTToken?: string; 7 | } 8 | -------------------------------------------------------------------------------- /src/types/traditional/remove-from-watch-list-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/RemoveFromWatchList.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface RemoveFromWatchListResponse extends StandardOutputFields { 5 | WatchListMaximum: number; 6 | } 7 | -------------------------------------------------------------------------------- /src/api/traditional/finding/index.ts: -------------------------------------------------------------------------------- 1 | enum calls { 2 | findCompletedItems, 3 | findItemsAdvanced, 4 | findItemsByCategory, 5 | findItemsByKeywords, 6 | findItemsByProduct, 7 | findItemsIneBayStores, 8 | getHistograms, 9 | getSearchKeywordsRecommendation, 10 | getVersion 11 | } 12 | 13 | export default calls; 14 | -------------------------------------------------------------------------------- /src/types/traditional/add-member-message-a-a-q-to-partner-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/AddMemberMessageAAQToPartner.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface AddMemberMessageAAQToPartnerResponse 5 | extends StandardOutputFields { 6 | } 7 | -------------------------------------------------------------------------------- /src/api/traditional/clientAlerts/index.ts: -------------------------------------------------------------------------------- 1 | import {EventType} from './types.js'; 2 | 3 | // https://developer.ebay.com/devzone/client-alerts/docs/CallRef/index.html 4 | enum calls { 5 | GetPublicAlerts, 6 | GetUserAlerts, 7 | Login, 8 | Logout 9 | } 10 | 11 | export { 12 | EventType 13 | }; 14 | 15 | export default calls; 16 | -------------------------------------------------------------------------------- /src/api/traditional/shopping/index.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/devzone/shopping/docs/callref/index.html 2 | enum calls { 3 | FindProducts, 4 | GetCategoryInfo, 5 | GeteBayTime, 6 | GetItemStatus, 7 | GetMultipleItems, 8 | GetShippingCosts, 9 | GetSingleItem, 10 | GetUserProfile 11 | } 12 | 13 | export default calls; 14 | -------------------------------------------------------------------------------- /src/types/traditional/add-second-chance-item-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/AddSecondChanceItem.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface AddSecondChanceItemResponse extends StandardOutputFields { 5 | ItemID: string; 6 | StartTime: string; 7 | } 8 | -------------------------------------------------------------------------------- /examples/restful/sell/account.getPrivileges.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | eBay.sell.account.getPrivileges().then(order => { 7 | console.log('privileges', JSON.stringify(order, null, 2)); 8 | }).catch(e => { 9 | console.error(e); 10 | }); 11 | -------------------------------------------------------------------------------- /src/types/traditional/verify-add-second-chance-item-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/VerifyAddSecondChanceItem.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface VerifyAddSecondChanceItemResponse 5 | extends StandardOutputFields { 6 | StartTime: string; 7 | } 8 | -------------------------------------------------------------------------------- /examples/traditional/merchandising.getMostWatchedItems.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | eBay.merchandising.getMostWatchedItems().then(result => { 7 | console.log(JSON.stringify(result, null, 2)); 8 | }).catch(e => { 9 | console.log(e); 10 | }); 11 | -------------------------------------------------------------------------------- /examples/traditional/trading.GetAccount.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | eBay.trading.GetAccount(null, { 6 | sign: true 7 | }).then(result => { 8 | console.log(JSON.stringify(result, null, 2)); 9 | }).catch(e => { 10 | console.error(e); 11 | }); 12 | 13 | -------------------------------------------------------------------------------- /scripts/update-readme-release.cjs: -------------------------------------------------------------------------------- 1 | const regex = /`(v\d+\.\d+\.\d+)` is the latest release\./ 2 | 3 | module.exports.readVersion = function(contents) { 4 | return contents.match(regex)[1] 5 | } 6 | 7 | module.exports.writeVersion = function(contents, version) { 8 | return contents.replace(regex, "`v" + version + "` is the latest release.") 9 | } 10 | -------------------------------------------------------------------------------- /examples/restful/buy/items.getItem.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | eBay.buy.browse.getItem('v1|382282567190|651094235351') 7 | .then(item => { 8 | console.log(JSON.stringify(item, null, 2)); 9 | }) 10 | .catch(e => { 11 | console.log(e); 12 | }); -------------------------------------------------------------------------------- /src/types/traditional/get-message-preferences-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetMessagePreferences.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface GetMessagePreferencesResponse extends StandardOutputFields { 5 | ASQPreferences: { 6 | Subject?: string; 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /examples/traditional/trading.GeteBayOfficialTime.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | (async () => { 7 | try { 8 | const time = await eBay.trading.GeteBayOfficialTime(); 9 | console.log(time); 10 | } catch (error) { 11 | console.log(error); 12 | } 13 | })(); -------------------------------------------------------------------------------- /examples/restful/sell/finances.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | eBay.sell.finances.sign.getSellerFundsSummary().then(result => { 7 | console.log('result', JSON.stringify(result, null, 2)); 8 | }).catch(e => { 9 | console.error(JSON.stringify(e, null, 2)); 10 | }); 11 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.log 3 | *.enc 4 | src 5 | tsconfig.json 6 | tslint.json 7 | test 8 | examples 9 | *.iml 10 | .nyc_output 11 | coverage 12 | scripts 13 | proxy 14 | specs 15 | .github 16 | index.html 17 | .travis.yml 18 | rollup.config.js 19 | .babelrc 20 | .mocharc.json 21 | .versionrc.json 22 | tsconfig.cjs.json 23 | CHANGELOG.md 24 | SUMMARY.md 25 | CONTRIBUTING.md -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # How to run the examples 2 | 3 | ## Node 20 4 | ```bash 5 | node --loader ts-node/esm examples/restful/buy/items.getItem.ts 6 | ``` 7 | 8 | ## Set the environments variables: 9 | EBAY_APP_ID= 10 | EBAY_CERT_ID= 11 | EBAY_DEV_ID= 12 | EBAY_RU_NAME= 13 | DEBUGX=ebay:*; 14 | 15 | ## Run 16 | ```bash 17 | ts-node examples/restful/buy/items.getItem.ts 18 | ``` -------------------------------------------------------------------------------- /examples/traditional/trading.GetMultipleItems.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | eBay.shopping.GetMultipleItems({ 7 | ItemID: '256186199138' 8 | }).then(result => { 9 | console.log(JSON.stringify(result, null, 2)); 10 | }).catch(e => { 11 | console.error(e); 12 | }); 13 | 14 | -------------------------------------------------------------------------------- /src/api/base.ts: -------------------------------------------------------------------------------- 1 | import {AxiosRequest, IEBayApiRequest} from '../request.js'; 2 | import {AppConfig} from '../types/index.js'; 3 | 4 | /** 5 | * Abstract superclass. 6 | */ 7 | export default abstract class Base { 8 | protected constructor(public readonly config: AppConfig, public readonly req: IEBayApiRequest = new AxiosRequest(config.axiosConfig)) { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/restful/sell/fullfillment.getOrder.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | eBay.sell.fulfillment.getOrder('11-06241-16499').then(order => { 7 | console.log('order', JSON.stringify(order, null, 2)); 8 | }).catch(e => { 9 | console.error(JSON.stringify(e, null, 2)); 10 | }); 11 | -------------------------------------------------------------------------------- /examples/traditional/shopping.GetUserProfile.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | // @ts-ignore 3 | import eBayApi from '../../src/eBayApi.js'; 4 | 5 | const eBay = eBayApi.fromEnv(); 6 | 7 | (async () => { 8 | const result = await eBay.shopping.GetUserProfile({ 9 | UserID: 'userId', 10 | IncludeSelector: 'Details' 11 | }); 12 | 13 | console.log(result); 14 | })() -------------------------------------------------------------------------------- /examples/restful/postOrder/return.getReturn.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | (async () => { 7 | try { 8 | const summary = await eBay.postOrder.return.getReturn('5132021997'); 9 | console.log(summary); 10 | } catch (error) { 11 | console.error(error); 12 | } 13 | })(); -------------------------------------------------------------------------------- /test/api/jsonfile.ts: -------------------------------------------------------------------------------- 1 | import {readFileSync} from 'fs'; 2 | import {dirname, join} from 'path'; 3 | import {fileURLToPath} from 'url'; 4 | 5 | export const readJSONSync = (path: string, metaUrl: string) => JSON.parse(readFileSync(join(dirname(fileURLToPath(metaUrl)), path), 'utf-8')); 6 | export const readSpecs = (path: string, metaUrl: string) => readJSONSync('../../../../specs/' + path, metaUrl) -------------------------------------------------------------------------------- /examples/traditional/trading.GetMyMessages.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | eBay.trading.GetMyMessages({ 7 | Folder: 0, 8 | DetailLevel: 'ReturnHeaders' 9 | }).then(result => { 10 | console.log(JSON.stringify(result, null, 2)); 11 | }).catch(e => { 12 | console.error(e); 13 | }); 14 | -------------------------------------------------------------------------------- /src/types/traditional/set-store-categories-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/SetStoreCategories.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface SetStoreCategoriesResponse extends StandardOutputFields { 5 | Status: 'Complete' | 'CustomCode' | 'Failed' | 'InProgress' | 'Pending'; 6 | TaskID: bigint; 7 | } 8 | -------------------------------------------------------------------------------- /src/types/traditional/respond-to-best-offer-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/RespondToBestOffer.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface RespondToBestOfferResponse extends StandardOutputFields { 5 | RespondToBestOffer: { 6 | BestOffer: { 7 | CallStatus: string; 8 | }; 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /examples/traditional/shopping.GetSingleItem.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | eBay.shopping.GetSingleItem({ 7 | ItemID: '255734197431', 8 | IncludeSelector: 'Details' 9 | }).then(result => { 10 | console.log(JSON.stringify(result, null, 2)); 11 | }).catch(e => { 12 | console.error(e); 13 | }); 14 | 15 | -------------------------------------------------------------------------------- /examples/restful/developer/analytics.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | (async () => { 7 | try { 8 | const rateLimits = await eBay.developer.analytics.getRateLimits(); 9 | console.log(JSON.stringify(rateLimits, null, 2)); 10 | } catch (error) { 11 | console.error(error); 12 | } 13 | })(); 14 | -------------------------------------------------------------------------------- /src/types/traditional/ve-r-o-report-items-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/VeROReportItems.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface VeROReportItemsResponse extends StandardOutputFields { 5 | VeROReportPacketStatus?: 6 | | 'CustomCode' 7 | | 'InProcess' 8 | | 'Processed' 9 | | 'Received'; 10 | } 11 | -------------------------------------------------------------------------------- /examples/restful/postOrder/inquiry.getInquiry.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | (async () => { 7 | try { 8 | const summary = await eBay.postOrder.inquiry.getInquiry('5222222222'); 9 | console.log(JSON.stringify(summary, null, 2)); 10 | } catch (error) { 11 | console.error(error); 12 | } 13 | })(); 14 | -------------------------------------------------------------------------------- /examples/restful/sell/metadata.getItemConditionPolicies.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | eBay.sell.metadata.getItemConditionPolicies('EBAY_US', 'categoryId:{95672}').then(result => { 7 | console.log('result', JSON.stringify(result, null, 2)); 8 | }).catch(e => { 9 | console.error(JSON.stringify(e, null, 2)); 10 | }); 11 | -------------------------------------------------------------------------------- /examples/restful/developer/keyManagement.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | (async () => { 7 | try { 8 | const signingKey = await eBay.developer.keyManagement.createSigningKey('ED25519'); 9 | console.log(JSON.stringify(signingKey, null, 2)); 10 | } catch (error) { 11 | console.error(error); 12 | } 13 | })(); 14 | -------------------------------------------------------------------------------- /test/api/restful/developer/index.ts: -------------------------------------------------------------------------------- 1 | import {Analytics, KeyManagement} from '../../../../src/api/restful/developer/index.js'; 2 | import {readSpecs} from '../../jsonfile.js'; 3 | 4 | const tests = new Map(); 5 | tests.set(Analytics, readSpecs( 'developer_analytics_v1_beta_oas3.json', import.meta.url)); 6 | tests.set(KeyManagement, readSpecs('developer_key_management_v1_oas3.json', import.meta.url)); 7 | 8 | export default tests; -------------------------------------------------------------------------------- /examples/traditional/finding.findItemsAdvanced.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | // @ts-ignore 3 | import eBayApi from '../../src/eBayApi.js'; 4 | 5 | const eBay = eBayApi.fromEnv(); 6 | 7 | eBay.finding.findItemsAdvanced({ 8 | itemFilter: [{ 9 | name: 'Seller', 10 | value: 'hendt_de' 11 | }] 12 | }).then(result => { 13 | console.log(JSON.stringify(result, null, 2)); 14 | }).catch(e => { 15 | console.log(e); 16 | }) -------------------------------------------------------------------------------- /examples/restful/buy/browse.search.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | eBay.buy.browse.search({ 7 | q: 'shirt', 8 | category_ids: '15724', 9 | aspect_filter: 'categoryId:15724,Color:{Red}' 10 | }) 11 | .then(result => { 12 | console.log(JSON.stringify(result, null, 2)); 13 | }) 14 | .catch(e => { 15 | console.log(e); 16 | }); -------------------------------------------------------------------------------- /src/api/restful/postOrder/index.ts: -------------------------------------------------------------------------------- 1 | import Cancellation from './cancellation/index.js'; 2 | import Case from './case/index.js'; 3 | import Inquiry from './inquiry/index.js'; 4 | import Return from './return/index.js'; 5 | 6 | export type PostOrder = { 7 | cancellation: Cancellation, 8 | case: Case, 9 | inquiry: Inquiry, 10 | return: Return 11 | }; 12 | 13 | export { 14 | Cancellation, 15 | Case, 16 | Inquiry, 17 | Return 18 | }; 19 | -------------------------------------------------------------------------------- /src/types/traditional/get-tax-table-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetTaxTable.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface GetTaxTableResponse extends StandardOutputFields { 5 | TaxTable: { 6 | TaxJurisdiction?: { 7 | JurisdictionID?: string; 8 | SalesTaxPercent?: number; 9 | ShippingIncludedInTax?: boolean; 10 | }; 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /src/types/traditional/add-member-messages-a-a-q-to-bidder-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/AddMemberMessagesAAQToBidder.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface AddMemberMessagesAAQToBidderResponse 5 | extends StandardOutputFields { 6 | AddMemberMessagesAAQToBidderResponseContainer: { 7 | Ack: 'CustomCode' | 'Failure' | 'PartialFailure' | 'Success' | 'Warning'; 8 | CorrelationID: string; 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /examples/traditional/trading.GetMyeBaySelling.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | eBay.trading.GetMyeBaySelling({ 7 | SoldList: { 8 | Include: true, 9 | OrderStatusFilter: 'AwaitingPayment', 10 | Pagination: { 11 | EntriesPerPage: 20, 12 | PageNumber: 1 13 | } 14 | } 15 | }).then(result => { 16 | console.log(JSON.stringify(result, null, 2)); 17 | }).catch(e => { 18 | console.error(e); 19 | }); 20 | -------------------------------------------------------------------------------- /src/types/traditional/add-to-item-description-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/AddToItemDescription.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface AddToItemDescriptionResponse extends StandardOutputFields { 5 | DuplicateInvocationDetails?: { 6 | DuplicateInvocationID?: string; 7 | InvocationTrackingID?: string; 8 | Status?: 'CustomCode' | 'Failure' | 'InProgress' | 'Success'; 9 | }; 10 | Message?: string; 11 | } 12 | -------------------------------------------------------------------------------- /.versionrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "# eBay API Changelog", 3 | "repository": { 4 | "host": "https://github.com/hendt/ebay-api.git", 5 | "url": "https://github.com/hendt/ebay-api.git" 6 | }, 7 | "bumpFiles": [ 8 | { 9 | "filename": "package.json", 10 | "type": "json" 11 | }, 12 | { 13 | "filename": "package-lock.json", 14 | "type": "json" 15 | }, 16 | { 17 | "filename": "README.md", 18 | "updater": "./scripts/update-readme-release.cjs" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /test/api/restful/postOrder/index.ts: -------------------------------------------------------------------------------- 1 | import {Cancellation, Case, Inquiry, Return} from '../../../../src/api/restful/postOrder/index.js'; 2 | import {readSpecs} from '../../jsonfile.js'; 3 | 4 | const tests = new Map(); 5 | tests.set(Cancellation, readSpecs( 'cancellation_oas3.json', import.meta.url)); 6 | tests.set(Case, readSpecs( 'case_oas3.json', import.meta.url)); 7 | tests.set(Inquiry, readSpecs( 'inquiry_oas3.json', import.meta.url)); 8 | tests.set(Return, readSpecs( 'return_oas3.json', import.meta.url)); 9 | 10 | export default tests; -------------------------------------------------------------------------------- /src/types/traditional/get-user-contact-details-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetUserContactDetails.html#Output 2 | import type { CountryCodeType, StandardOutputFields } from './common.js'; 3 | 4 | export interface GetUserContactDetailsResponse extends StandardOutputFields { 5 | ContactAddress: { 6 | CityName?: string; 7 | CompanyName: string; 8 | Country: CountryCodeType; 9 | Name: string; 10 | Phone: string; 11 | StateOrProvince?: string; 12 | }; 13 | RegistrationDate: string; 14 | UserID: string; 15 | } 16 | -------------------------------------------------------------------------------- /examples/restful/sell/getOrders.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | eBay.OAuth2.setScope([ 7 | 'https://api.ebay.com/oauth/api_scope', 8 | 'https://api.ebay.com/oauth/api_scope/sell.fulfillment', 9 | 'https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly' 10 | ]) 11 | 12 | eBay.sell.fulfillment.getOrders({ 13 | limit: 5 14 | }).then(order => { 15 | console.log('order', JSON.stringify(order, null, 2)); 16 | }).catch(e => { 17 | console.error(JSON.stringify(e, null, 2)); 18 | }); 19 | -------------------------------------------------------------------------------- /src/types/traditional/get-token-status-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetTokenStatus.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface GetTokenStatusResponse extends StandardOutputFields { 5 | TokenStatus: { 6 | EIASToken: string; 7 | ExpirationTime: string; 8 | RevocationTime: string; 9 | Status: 10 | | 'Active' 11 | | 'CustomCode' 12 | | 'Expired' 13 | | 'Invalid' 14 | | 'RevokedByApp' 15 | | 'RevokedByeBay' 16 | | 'RevokedByUser'; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /examples/restful/buy/marketing.getAlsoBoughtProducts.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../../src/eBayApi.js'; 3 | 4 | const eBay = eBayApi.fromEnv(); 5 | 6 | // Check OAuth Scope if this really works for you: https://developer.ebay.com/my/keys 7 | eBay.OAuth2.setScope([ 8 | 'https://api.ebay.com/oauth/api_scope', 9 | 'https://api.ebay.com/oauth/api_scope/buy.marketing' 10 | ]); 11 | 12 | eBay.buy.marketing.getAlsoBoughtByProduct({ 13 | gtin: '8806088687681' 14 | }).then(products => { 15 | console.log(JSON.stringify(products, null, 2)); 16 | }).catch(e => { 17 | console.log(e); 18 | }); 19 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "node16", 5 | "outDir": "./dist", 6 | "lib": ["ES2020", "DOM"], 7 | "declaration": true, 8 | "moduleResolution": "node16", 9 | "sourceMap": false, 10 | "esModuleInterop": true, 11 | "resolveJsonModule": true, 12 | "strict": true, 13 | "noUnusedLocals": true, 14 | "noUnusedParameters": true, 15 | "noImplicitReturns": true, 16 | "noFallthroughCasesInSwitch": true, 17 | "removeComments": true 18 | }, 19 | "exclude": ["src/index.ts"], 20 | "include": ["src"], 21 | "ts-node": { 22 | "esm": true 23 | } 24 | } -------------------------------------------------------------------------------- /src/types/traditional/revise-inventory-status-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/ReviseInventoryStatus.html#Output 2 | import type { CurrencyCodeType, StandardOutputFields } from './common.js'; 3 | 4 | export interface ReviseInventoryStatusResponse extends StandardOutputFields { 5 | Fees: { 6 | Fee: { 7 | Fee: number | { value: number; currencyID: CurrencyCodeType }; 8 | Name: string; 9 | PromotionalDiscount: 10 | | number 11 | | { value: number; currencyID: CurrencyCodeType }; 12 | }; 13 | ItemID: string; 14 | }; 15 | InventoryStatus: { 16 | ItemID: string; 17 | SKU: string; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /src/api/restful/buy/index.ts: -------------------------------------------------------------------------------- 1 | import Browse from './browse/index.js'; 2 | import Feed from './feed/index.js'; 3 | import Marketing from './marketing/index.js'; 4 | import Offer from './offer/index.js'; 5 | import Order from './order/index.js'; 6 | import Deal from './deal/index.js'; 7 | import MarketplaceInsights from './marketplaceInsights/index.js' 8 | 9 | export type Buy = { 10 | browse: Browse, 11 | deal: Deal 12 | feed: Feed, 13 | marketing: Marketing, 14 | marketplaceInsights: MarketplaceInsights 15 | offer: Offer, 16 | order: Order 17 | }; 18 | 19 | export { 20 | Browse, 21 | Deal, 22 | Feed, 23 | Marketing, 24 | MarketplaceInsights, 25 | Offer, 26 | Order 27 | }; 28 | -------------------------------------------------------------------------------- /src/types/traditional/end-items-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/EndItems.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface EndItemsResponse extends StandardOutputFields { 5 | EndItemResponseContainer: { 6 | CorrelationID?: string; 7 | EndTime: string; 8 | Errors?: { 9 | ErrorClassification?: 'CustomCode' | 'RequestError' | 'SystemError'; 10 | ErrorCode?: string; 11 | ErrorParameters?: { 12 | Value?: string; 13 | }; 14 | LongMessage?: string; 15 | SeverityCode?: 'CustomCode' | 'Error' | 'Warning'; 16 | ShortMessage?: string; 17 | }; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /examples/traditional/clientAlerts.GetPublicAlerts.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import eBayApi from '../../src/eBayApi.js'; 3 | 4 | import {EventType} from '../../src/api/traditional/clientAlerts'; 5 | 6 | const eBay = eBayApi.fromEnv(); 7 | 8 | eBay.clientAlerts.GetPublicAlerts({ 9 | ChannelDescriptor: [ 10 | { 11 | ChannelType: 'Item', 12 | ChannelID: 174028462015, 13 | EventType: [EventType.ItemEnded] 14 | }, 15 | { 16 | ChannelType: 'Item', 17 | ChannelID: 180434053857, 18 | EventType: [EventType.ItemEnded] 19 | } 20 | ] 21 | }).then(result => { 22 | console.log(JSON.stringify(result, null, 2)); 23 | }).catch(e => { 24 | console.log(e); 25 | }); 26 | -------------------------------------------------------------------------------- /src/nanoevents.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/ai/nanoevents 2 | export type EventCallback = (...args: any) => void 3 | 4 | export let createNanoEvents = () => ({ 5 | events: {} as Record, 6 | emit(event: string, ...args: any[]) { 7 | const callbacks = this.events[event] || []; 8 | for (let i = 0, length = callbacks.length; i < length; i++) { 9 | callbacks[i](...args); 10 | } 11 | }, 12 | on(event: string, cb: EventCallback) { 13 | if (this.events[event]) { 14 | this.events[event].push(cb); 15 | } else { 16 | this.events[event] = [cb]; 17 | } 18 | return () => { 19 | this.events[event] = this.events[event]?.filter(i => cb !== i); 20 | }; 21 | } 22 | }); -------------------------------------------------------------------------------- /src/types/traditional/verify-add-fixed-price-item-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/VerifyAddFixedPriceItem.html#Output 2 | import type { CurrencyCodeType, StandardOutputFields } from './common.js'; 3 | 4 | export interface VerifyAddFixedPriceItemResponse extends StandardOutputFields { 5 | CategoryID?: string; 6 | DiscountReason?: 'CustomCode' | 'Promotion' | 'SpecialOffer'; 7 | Fees: { 8 | Fee: { 9 | Fee: number | { value: number; currencyID: CurrencyCodeType }; 10 | Name: string; 11 | PromotionalDiscount: 12 | | number 13 | | { value: number; currencyID: CurrencyCodeType }; 14 | }; 15 | }; 16 | ItemID: string; 17 | SKU?: string; 18 | } 19 | -------------------------------------------------------------------------------- /src/api/restful/commerce/index.ts: -------------------------------------------------------------------------------- 1 | import Catalog from './catalog/index.js'; 2 | import Charity from './charity/index.js'; 3 | import Identity from './identity/index.js'; 4 | import Media from './media/index.js'; 5 | import Notification from './notification/index.js'; 6 | import Taxonomy from './taxonomy/index.js'; 7 | import Translation from './translation/index.js'; 8 | 9 | export type Commerce = { 10 | catalog: Catalog; 11 | charity: Charity, 12 | identity: Identity; 13 | notification: Notification 14 | taxonomy: Taxonomy; 15 | translation: Translation; 16 | media: Media; 17 | }; 18 | 19 | export { 20 | Catalog, 21 | Charity, 22 | Identity, 23 | Notification, 24 | Taxonomy, 25 | Translation, 26 | Media 27 | }; 28 | -------------------------------------------------------------------------------- /src/types/traditional/upload-site-hosted-pictures-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/UploadSiteHostedPictures.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface UploadSiteHostedPicturesResponse extends StandardOutputFields { 5 | SiteHostedPictureDetails: { 6 | BaseURL: string; 7 | ExternalPictureURL?: string; 8 | FullURL: string; 9 | PictureFormat: 'CustomCode' | 'GIF' | 'JPG' | 'PNG'; 10 | PictureName?: string; 11 | PictureSet: 'CustomCode' | 'Standard' | 'Supersize'; 12 | PictureSetMember: { 13 | MemberURL: string; 14 | PictureHeight: number; 15 | PictureWidth: number; 16 | }; 17 | UseByDate: string; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: wontfix 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | -------------------------------------------------------------------------------- /src/types/traditional/get-description-templates-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetDescriptionTemplates.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface GetDescriptionTemplatesResponse extends StandardOutputFields { 5 | DescriptionTemplate: { 6 | GroupID?: number; 7 | ID: number; 8 | ImageURL: string; 9 | Name: string; 10 | TemplateXML?: string; 11 | Type: 'CustomCode' | 'Layout' | 'Theme'; 12 | }; 13 | LayoutTotal: number; 14 | ObsoleteLayoutID?: number; 15 | ObsoleteThemeID?: number; 16 | ThemeGroup?: { 17 | GroupID?: number; 18 | GroupName?: string; 19 | ThemeID?: number; 20 | ThemeTotal?: number; 21 | }; 22 | ThemeTotal: number; 23 | } 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: dantio 7 | 8 | --- 9 | 10 | * [ ] Are you running the latest version? 11 | * [ ] Have you included sample input, output, error, and expected output? 12 | * [ ] Have you checked if you are using correct configuration? 13 | 14 | **Describe the bug** 15 | A clear and concise description of what the bug is. 16 | 17 | ### Code 18 | ```js 19 | Include the code being used 20 | ``` 21 | 22 | ### Output 23 | 24 | 25 | ### expected data 26 | 27 | 28 | **Would you like to work on this issue?** 29 | 30 | - [ ] Yes 31 | - [ ] No 32 | - [ ] Maybe 33 | -------------------------------------------------------------------------------- /src/api/restful/commerce/identity/index.ts: -------------------------------------------------------------------------------- 1 | import {operations} from '../../../../types/restful/specs/commerce_identity_v1_oas3.js'; 2 | import Restful, {OpenApi} from '../../index.js'; 3 | 4 | /** 5 | * Retrieves the authenticated user's account profile information. 6 | */ 7 | export default class Identity extends Restful implements OpenApi { 8 | 9 | static id = 'Identity'; 10 | 11 | get basePath(): string { 12 | return '/commerce/identity/v1'; 13 | } 14 | 15 | get subdomain(): string { 16 | return 'apiz'; 17 | } 18 | 19 | /** 20 | * This method retrieves the account profile information for an authenticated user, which requires a User access 21 | * token. What is returned is controlled by the scopes. 22 | */ 23 | public getUser() { 24 | return this.get(`/user/`); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/api/restful/commerce/translation/index.ts: -------------------------------------------------------------------------------- 1 | import {TranslateRequest} from '../../../../types/index.js'; 2 | import {operations} from '../../../../types/restful/specs/commerce_translation_v1_beta_oas3.js'; 3 | import Restful, {OpenApi} from '../../index.js'; 4 | 5 | /** 6 | * This API allows 3rd party developers to translate item title, description, search query. 7 | */ 8 | export default class Translation extends Restful implements OpenApi { 9 | 10 | static id = 'Translation'; 11 | 12 | get basePath(): string { 13 | return '/commerce/translation/v1_beta'; 14 | } 15 | 16 | /** 17 | * Translates input text inot a given language. 18 | * 19 | * @param body TranslateRequest 20 | */ 21 | public translate(body: TranslateRequest) { 22 | return this.post(`/translate`, body); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/types/traditional/verify-relist-item-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/VerifyRelistItem.html#Output 2 | import type { CurrencyCodeType, StandardOutputFields } from './common.js'; 3 | 4 | export interface VerifyRelistItemResponse extends StandardOutputFields { 5 | EndTime: string; 6 | Fees: { 7 | Fee: { 8 | Fee: number | { value: number; currencyID: CurrencyCodeType }; 9 | Name: string; 10 | PromotionalDiscount: 11 | | number 12 | | { value: number; currencyID: CurrencyCodeType }; 13 | }; 14 | }; 15 | ItemID: string; 16 | ProductSuggestions?: { 17 | ProductSuggestion?: { 18 | EPID?: string; 19 | Recommended?: boolean; 20 | StockPhoto?: string; 21 | Title?: string; 22 | }; 23 | }; 24 | StartTime: string; 25 | } 26 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thanks for being willing to contribute! 4 | 5 | ## Project setup 6 | 7 | 1. Fork and clone the repo 8 | 2. `$ npm install` to install dependencies 9 | 3. `$ npm run test` to test all scenario's 10 | 4. Create a branch for your PR 11 | 5. Try to include test cases for your code 12 | 6. Follow [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) for commit messages 13 | 14 | ## Commit and Push 15 | 16 | Once you completed making the change, Please make sure to run the tests before you commit your changes. You can run 17 | `npm run test` which will test your code. 18 | 19 | **Working on your first Pull Request?** 20 | [How to Contribute to an Open Source Project on GitHub](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github). 21 | Thanks to @kentcdodds for this amazing tutorial. -------------------------------------------------------------------------------- /src/api/restful/sell/listing/index.ts: -------------------------------------------------------------------------------- 1 | import {operations} from '../../../../types/restful/specs/sell_listing_v1_beta_oas3.js'; 2 | import Restful, {OpenApi} from '../../index.js'; 3 | 4 | /** 5 | * Enables a seller adding an ad or item on a Partner's site to automatically create an eBay listing draft using the item details from the Partner's site. 6 | */ 7 | export default class Listing extends Restful implements OpenApi { 8 | 9 | static id = 'Listing'; 10 | 11 | get basePath(): string { 12 | return '/sell/listing/v1_beta'; 13 | } 14 | 15 | /** 16 | * This call gives Partners the ability to create an eBay draft of a item for their seller using information from their site. 17 | * 18 | * @param data The ItemDraft 19 | */ 20 | public createItemDraft(data?: any) { 21 | return this.post(`/item_draft/`, data); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/types/traditional/verify-add-item-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/VerifyAddItem.html#Output 2 | import type { CurrencyCodeType, StandardOutputFields } from './common.js'; 3 | 4 | export interface VerifyAddItemResponse extends StandardOutputFields { 5 | CategoryID?: string; 6 | DiscountReason?: 'CustomCode' | 'Promotion' | 'SpecialOffer'; 7 | Fees: { 8 | Fee: { 9 | Fee: number | { value: number; currencyID: CurrencyCodeType }; 10 | Name: string; 11 | PromotionalDiscount: 12 | | number 13 | | { value: number; currencyID: CurrencyCodeType }; 14 | }; 15 | }; 16 | ItemID: string; 17 | ProductSuggestions?: { 18 | ProductSuggestion?: { 19 | EPID?: string; 20 | Recommended?: boolean; 21 | StockPhoto?: string; 22 | Title?: string; 23 | }; 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:recommended" 5 | ], 6 | "jsRules": {}, 7 | "rules": { 8 | "indent": [ 9 | true, 10 | "spaces", 11 | 2 12 | ], 13 | "object-literal-sort-keys": false, 14 | "quotemark": [ 15 | true, 16 | "single" 17 | ], 18 | "trailing-comma": [ 19 | false 20 | ], 21 | "variable-name": [ 22 | true, 23 | "check-format", 24 | "allow-leading-underscore", 25 | "allow-snake-case" 26 | ], 27 | "interface-over-type-literal": false, 28 | "arrow-parens": [ 29 | true, 30 | "ban-single-arg-parens" 31 | ], 32 | "no-bitwise": false, 33 | "no-empty-interface": false 34 | }, 35 | "rulesDirectory": [], 36 | "linterOptions": { 37 | "exclude": [ 38 | "src/types/restful/specs/**/*.ts" 39 | ] 40 | } 41 | } -------------------------------------------------------------------------------- /src/types/traditional/add-item-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/AddItem.html#Output 2 | import type { CurrencyCodeType, StandardOutputFields } from './common.js'; 3 | 4 | export interface AddItemResponse extends StandardOutputFields { 5 | CategoryID?: string; 6 | DiscountReason?: 'CustomCode' | 'Promotion' | 'SpecialOffer'; 7 | EndTime: string; 8 | Fees: { 9 | Fee: { 10 | Fee: number | { value: number; currencyID: CurrencyCodeType }; 11 | Name: string; 12 | PromotionalDiscount: 13 | | number 14 | | { value: number; currencyID: CurrencyCodeType }; 15 | }; 16 | }; 17 | ItemID: string; 18 | ProductSuggestions?: { 19 | ProductSuggestion?: { 20 | EPID?: string; 21 | Recommended?: boolean; 22 | StockPhoto?: string; 23 | Title?: string; 24 | }; 25 | }; 26 | StartTime: string; 27 | } 28 | -------------------------------------------------------------------------------- /test/api/restful/buy/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Browse, 3 | Deal, 4 | Feed, 5 | Marketing, 6 | MarketplaceInsights, 7 | Offer, 8 | Order 9 | } from '../../../../src/api/restful/buy/index.js'; 10 | import {readSpecs} from '../../jsonfile.js'; 11 | 12 | const tests = new Map(); 13 | tests.set(Browse, readSpecs('buy_browse_v1_oas3.json', import.meta.url)); 14 | tests.set(Feed, readSpecs('buy_feed_v1_beta_oas3.json', import.meta.url)); 15 | tests.set(Marketing, readSpecs('buy_marketing_v1_beta_oas3.json', import.meta.url)); 16 | tests.set(Offer, readSpecs('buy_offer_v1_beta_oas3.json', import.meta.url)); 17 | tests.set(Order, readSpecs('buy_order_v1_beta_oas3.json', import.meta.url)); 18 | tests.set(Deal, readSpecs('buy_deal_v1_oas3.json', import.meta.url)); 19 | tests.set(MarketplaceInsights, readSpecs('buy_marketplace_insights_v1_beta_oas3.json', import.meta.url)); 20 | 21 | export default tests; -------------------------------------------------------------------------------- /src/types/traditional/relist-item-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/RelistItem.html#Output 2 | import type { CurrencyCodeType, StandardOutputFields } from './common.js'; 3 | 4 | export interface RelistItemResponse extends StandardOutputFields { 5 | CategoryID?: string; 6 | DiscountReason?: 'CustomCode' | 'Promotion' | 'SpecialOffer'; 7 | EndTime: string; 8 | Fees: { 9 | Fee: { 10 | Fee: number | { value: number; currencyID: CurrencyCodeType }; 11 | Name: string; 12 | PromotionalDiscount: 13 | | number 14 | | { value: number; currencyID: CurrencyCodeType }; 15 | }; 16 | }; 17 | ItemID: string; 18 | ProductSuggestions?: { 19 | ProductSuggestion?: { 20 | EPID?: string; 21 | Recommended?: boolean; 22 | StockPhoto?: string; 23 | Title?: string; 24 | }; 25 | }; 26 | StartTime: string; 27 | } 28 | -------------------------------------------------------------------------------- /examples/traditional/authNAuth.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | // @ts-ignore 3 | import readline from 'readline'; 4 | import eBayApi from '../../src/eBayApi.js'; 5 | 6 | const eBay = eBayApi.fromEnv(); 7 | // DOCS: https://developer.ebay.com/devzone/xml/docs/howto/tokens/gettingtokens.html 8 | 9 | const rl = readline.createInterface({ 10 | input: process.stdin, 11 | output: process.stdout 12 | }); 13 | 14 | eBay.authNAuth.getSessionIdAndAuthUrl().then(({url, sessionId}) => { 15 | console.log('Authorize this app by visiting this url: ', url); 16 | 17 | rl.question('Press Enter after grant access', async () => { 18 | await eBay.authNAuth.obtainToken(sessionId); 19 | 20 | try { 21 | const time = await eBay.trading.GeteBayOfficialTime(); 22 | console.log(time); 23 | } catch (error) { 24 | console.error(error) 25 | } finally { 26 | rl.close(); 27 | } 28 | 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /src/types/traditional/revise-item-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/ReviseItem.html#Output 2 | import type { CurrencyCodeType, StandardOutputFields } from './common.js'; 3 | 4 | export interface ReviseItemResponse extends StandardOutputFields { 5 | CategoryID?: string; 6 | DiscountReason?: 'CustomCode' | 'Promotion' | 'SpecialOffer'; 7 | EndTime: string; 8 | Fees: { 9 | Fee: { 10 | Fee: number | { value: number; currencyID: CurrencyCodeType }; 11 | Name: string; 12 | PromotionalDiscount: 13 | | number 14 | | { value: number; currencyID: CurrencyCodeType }; 15 | }; 16 | }; 17 | ItemID: string; 18 | ProductSuggestions?: { 19 | ProductSuggestion?: { 20 | EPID?: string; 21 | Recommended?: boolean; 22 | StockPhoto?: string; 23 | Title?: string; 24 | }; 25 | }; 26 | StartTime: string; 27 | VerifyOnly?: boolean; 28 | } 29 | -------------------------------------------------------------------------------- /src/types/traditional/get-categories-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetCategories.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface GetCategoriesResponse extends StandardOutputFields { 5 | CategoryArray: { 6 | Category?: { 7 | AutoPayEnabled?: boolean; 8 | B2BVATEnabled?: boolean; 9 | BestOfferEnabled?: boolean; 10 | CategoryID: string; 11 | CategoryLevel: number; 12 | CategoryName: string; 13 | CategoryParentID: string; 14 | Expired: boolean; 15 | LSD: boolean; 16 | LeafCategory: boolean; 17 | ORPA: boolean; 18 | ORRA?: boolean; 19 | Virtual: boolean; 20 | }; 21 | }; 22 | CategoryCount: number; 23 | CategoryVersion: string; 24 | MinimumReservePrice: number; 25 | ReduceReserveAllowed: boolean; 26 | ReservePriceAllowed: boolean; 27 | UpdateTime: string; 28 | } 29 | -------------------------------------------------------------------------------- /src/types/traditional/add-fixed-price-item-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/AddFixedPriceItem.html#Output 2 | import type { CurrencyCodeType, StandardOutputFields } from './common.js'; 3 | 4 | export interface AddFixedPriceItemResponse extends StandardOutputFields { 5 | CategoryID?: string; 6 | DiscountReason?: 'CustomCode' | 'Promotion' | 'SpecialOffer'; 7 | EndTime?: string; 8 | Fees: { 9 | Fee: { 10 | Fee: number | { value: number; currencyID: CurrencyCodeType }; 11 | Name: string; 12 | PromotionalDiscount: 13 | | number 14 | | { value: number; currencyID: CurrencyCodeType }; 15 | }; 16 | }; 17 | ItemID: string; 18 | ProductSuggestions?: { 19 | ProductSuggestion?: { 20 | EPID?: string; 21 | Recommended?: boolean; 22 | StockPhoto?: string; 23 | Title?: string; 24 | }; 25 | }; 26 | SKU?: string; 27 | StartTime: string; 28 | } 29 | -------------------------------------------------------------------------------- /test/api/restful/commerce/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Catalog, 3 | Charity, 4 | Identity, 5 | Media, 6 | Notification, 7 | Taxonomy, 8 | Translation 9 | } from '../../../../src/api/restful/commerce/index.js'; 10 | import {readSpecs} from '../../jsonfile.js'; 11 | 12 | const tests = new Map(); 13 | tests.set(Catalog, readSpecs( 'commerce_catalog_v1_beta_oas3.json', import.meta.url)); 14 | tests.set(Identity, readSpecs( 'commerce_identity_v1_oas3.json', import.meta.url)); 15 | tests.set(Taxonomy, readSpecs( 'commerce_taxonomy_v1_oas3.json', import.meta.url)); 16 | tests.set(Translation, readSpecs('commerce_translation_v1_beta_oas3.json', import.meta.url)); 17 | tests.set(Charity, readSpecs('commerce_charity_v1_oas3.json', import.meta.url)); 18 | tests.set(Notification, readSpecs('commerce_notification_v1_oas3.json', import.meta.url)); 19 | tests.set(Media, readSpecs('commerce_media_v1_beta_oas3.json', import.meta.url)); 20 | 21 | export default tests; -------------------------------------------------------------------------------- /src/types/traditional/get-store-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetStore.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface GetStoreResponse extends StandardOutputFields { 5 | Store: { 6 | CustomCategories: { 7 | CustomCategory: { 8 | CategoryID: bigint; 9 | ChildCategory: { 10 | CategoryID: bigint; 11 | ChildCategory: { 12 | CategoryID?: bigint; 13 | ChildCategory?: any; 14 | Name?: string; 15 | Order?: number; 16 | }; 17 | Name: string; 18 | Order: number; 19 | }; 20 | Name: string; 21 | Order: number; 22 | }; 23 | }; 24 | Description: string; 25 | LastOpenedTime?: string; 26 | Logo?: { 27 | URL?: string; 28 | }; 29 | Name: string; 30 | URL?: string; 31 | URLPath?: string; 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /src/types/traditional/relist-fixed-price-item-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/RelistFixedPriceItem.html#Output 2 | import type { CurrencyCodeType, StandardOutputFields } from './common.js'; 3 | 4 | export interface RelistFixedPriceItemResponse extends StandardOutputFields { 5 | CategoryID?: string; 6 | DiscountReason?: 'CustomCode' | 'Promotion' | 'SpecialOffer'; 7 | EndTime: string; 8 | Fees: { 9 | Fee: { 10 | Fee: number | { value: number; currencyID: CurrencyCodeType }; 11 | Name: string; 12 | PromotionalDiscount: 13 | | number 14 | | { value: number; currencyID: CurrencyCodeType }; 15 | }; 16 | }; 17 | ItemID: string; 18 | ProductSuggestions?: { 19 | ProductSuggestion?: { 20 | EPID?: string; 21 | Recommended?: boolean; 22 | StockPhoto?: string; 23 | Title?: string; 24 | }; 25 | }; 26 | SKU?: string; 27 | StartTime: string; 28 | } 29 | -------------------------------------------------------------------------------- /src/types/traditional/revise-fixed-price-item-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/ReviseFixedPriceItem.html#Output 2 | import type { CurrencyCodeType, StandardOutputFields } from './common.js'; 3 | 4 | export interface ReviseFixedPriceItemResponse extends StandardOutputFields { 5 | CategoryID?: string; 6 | DiscountReason?: 'CustomCode' | 'Promotion' | 'SpecialOffer'; 7 | EndTime: string; 8 | Fees: { 9 | Fee: { 10 | Fee: number | { value: number; currencyID: CurrencyCodeType }; 11 | Name: string; 12 | PromotionalDiscount: 13 | | number 14 | | { value: number; currencyID: CurrencyCodeType }; 15 | }; 16 | }; 17 | ItemID: string; 18 | ProductSuggestions?: { 19 | ProductSuggestion?: { 20 | EPID?: string; 21 | Recommended?: boolean; 22 | StockPhoto?: string; 23 | Title?: string; 24 | }; 25 | }; 26 | SKU?: string; 27 | StartTime: string; 28 | } 29 | -------------------------------------------------------------------------------- /src/types/traditional/get-ve-r-o-report-status-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetVeROReportStatus.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface GetVeROReportStatusResponse extends StandardOutputFields { 5 | ItemsPerPage?: number; 6 | PageNumber?: number; 7 | PaginationResult?: { 8 | TotalNumberOfEntries?: number; 9 | TotalNumberOfPages?: number; 10 | }; 11 | ReportedItemDetails?: { 12 | ReportedItem?: { 13 | ItemID?: string; 14 | ItemReasonForFailure?: string; 15 | ItemStatus?: 16 | | 'ClarificationRequired' 17 | | 'CustomCode' 18 | | 'Received' 19 | | 'Removed' 20 | | 'SubmissionFailed' 21 | | 'Submitted'; 22 | }; 23 | }; 24 | VeROReportPacketID?: bigint; 25 | VeROReportPacketStatus?: 26 | | 'CustomCode' 27 | | 'InProcess' 28 | | 'Processed' 29 | | 'Received'; 30 | } 31 | -------------------------------------------------------------------------------- /test/api/factory.spec.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai'; 2 | import 'mocha'; 3 | // @ts-ignore 4 | import sinon from 'sinon'; 5 | import ApiFactory from '../../src/api/apiFactory.js'; 6 | import {IEBayApiRequest} from '../../src/request.js'; 7 | import {eBayConfig} from '../../src/types/index.js'; 8 | 9 | describe('FactoryTest', () => { 10 | let config: eBayConfig; 11 | const request: IEBayApiRequest = { 12 | get: sinon.stub(), 13 | delete: sinon.stub(), 14 | put: sinon.stub(), 15 | post: sinon.stub(), 16 | postForm: sinon.stub(), 17 | instance: sinon.stub() 18 | }; 19 | 20 | beforeEach(() => { 21 | config = {appId: 'appId', certId: 'certId', sandbox: true, siteId: 0, devId: 'devId'}; 22 | }); 23 | 24 | it('Throws an error if siteId is not defined', () => { 25 | delete config.siteId; 26 | const factory = new ApiFactory(config, request); 27 | expect(factory.createTradingApi.bind(factory)).to.throw(/siteId/); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Daniil Tomilow 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/auth/index.ts: -------------------------------------------------------------------------------- 1 | import Base from '../api/base.js'; 2 | import {IEBayApiRequest} from '../request.js'; 3 | import {AppConfig} from '../types/index.js'; 4 | import AuthNAuth from './authNAuth.js'; 5 | import OAuth2 from './oAuth2.js'; 6 | 7 | /** 8 | * Container with Auth'N'Auth and OAuth2. 9 | */ 10 | export default class Auth extends Base { 11 | public readonly authNAuth: AuthNAuth; 12 | public readonly oAuth2: OAuth2; 13 | // tslint:disable-next-line:variable-name 14 | public readonly OAuth2: OAuth2; 15 | 16 | constructor(config: AppConfig, req: IEBayApiRequest) { 17 | super(config, req); 18 | this.authNAuth = new AuthNAuth(this.config, this.req); 19 | this.OAuth2 = new OAuth2(this.config, this.req); 20 | this.oAuth2 = this.OAuth2; 21 | } 22 | 23 | public async getHeaderAuthorization(useIaf: boolean) { 24 | if (this.authNAuth.eBayAuthToken) { 25 | return { 26 | Authorization: 'Token ' + this.authNAuth.eBayAuthToken 27 | } 28 | } 29 | 30 | const accessToken = await this.OAuth2.getAccessToken(); 31 | return { 32 | Authorization: (useIaf ? 'IAF ' : 'Bearer ') + accessToken 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/types/traditional/get-ve-r-o-reason-code-details-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetVeROReasonCodeDetails.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface GetVeROReasonCodeDetailsResponse extends StandardOutputFields { 5 | VeROReasonCodeDetails: { 6 | VeROSiteDetail: { 7 | ReasonCodeDetail: { 8 | BriefText: string; 9 | DetailedText: string; 10 | }; 11 | Site: 12 | | 'Australia' 13 | | 'Austria' 14 | | 'Belgium_Dutch' 15 | | 'Belgium_French' 16 | | 'Canada' 17 | | 'CanadaFrench' 18 | | 'CustomCode' 19 | | 'Cyprus' 20 | | 'Czechia' 21 | | 'eBayMotors' 22 | | 'France' 23 | | 'Germany' 24 | | 'HongKong' 25 | | 'India' 26 | | 'Ireland' 27 | | 'Italy' 28 | | 'Malaysia' 29 | | 'Netherlands' 30 | | 'Philippines' 31 | | 'Poland' 32 | | 'Russia' 33 | | 'Singapore' 34 | | 'Spain' 35 | | 'Switzerland' 36 | | 'UK' 37 | | 'US'; 38 | }; 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /src/enums/apiEnums.ts: -------------------------------------------------------------------------------- 1 | export enum SiteId { 2 | EBAY_US = 0, 3 | EBAY_ENCA = 2, 4 | EBAY_GB = 3, 5 | EBAY_AU = 15, 6 | EBAY_AT = 16, 7 | EBAY_FRBE = 23, 8 | EBAY_FR = 71, 9 | EBAY_DE = 77, 10 | EBAY_MOTOR = 100, 11 | EBAY_IT = 101, 12 | EBAY_NLBE = 123, 13 | EBAY_NL = 146, 14 | EBAY_ES = 186, 15 | EBAY_CH = 193, 16 | EBAY_HK = 201, 17 | EBAY_IN = 203, 18 | EBAY_IE = 205, 19 | EBAY_MY = 207, 20 | EBAY_FRCA = 210, 21 | EBAY_PH = 211, 22 | EBAY_PL = 212, 23 | EBAY_SG = 216 24 | } 25 | 26 | export enum MarketplaceId { 27 | EBAY_US = 'EBAY_US', 28 | EBAY_AT = 'EBAY_AT', 29 | EBAY_AU = 'EBAY_AU', 30 | EBAY_BE = 'EBAY_BE', 31 | EBAY_CA = 'EBAY_CA', 32 | EBAY_CH = 'EBAY_CH', 33 | EBAY_DE = 'EBAY_DE', 34 | EBAY_ES = 'EBAY_ES', 35 | EBAY_FR = 'EBAY_FR', 36 | EBAY_GB = 'EBAY_GB', 37 | EBAY_HK = 'EBAY_HK', 38 | EBAY_IE = 'EBAY_IE', 39 | EBAY_IN = 'EBAY_IN', 40 | EBAY_IT = 'EBAY_IT', 41 | EBAY_MY = 'EBAY_MY', 42 | EBAY_NL = 'EBAY_NL', 43 | EBAY_PH = 'EBAY_PH', 44 | EBAY_PL = 'EBAY_PL', 45 | EBAY_SG = 'EBAY_SG', 46 | EBAY_TH = 'EBAY_TH', 47 | EBAY_TW = 'EBAY_TW', 48 | EBAY_VN = 'EBAY_VN', 49 | EBAY_MOTORS_US = 'EBAY_MOTORS_US' 50 | } -------------------------------------------------------------------------------- /examples/restful/authFlow.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import readline from 'readline'; 3 | import eBayApi from '../../src/eBayApi.js'; 4 | 5 | const eBay = eBayApi.fromEnv(); 6 | eBay.OAuth2.setScope([ 7 | 'https://api.ebay.com/oauth/api_scope', 8 | 'https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly', 9 | 'https://api.ebay.com/oauth/api_scope/sell.fulfillment' 10 | ]); 11 | 12 | const url = eBay.OAuth2.generateAuthUrl(); 13 | 14 | console.log('Authorize this app by visiting this url:', url); 15 | 16 | const rl = readline.createInterface({ 17 | input: process.stdin, 18 | output: process.stdout, 19 | }); 20 | 21 | rl.question('Enter the code from that page here (from the url query ?code=) : ', async (code: string) => { 22 | rl.close(); 23 | code = decodeURIComponent(code); 24 | console.log('Enter code', code); 25 | const token = await eBay.OAuth2.getToken(code); 26 | console.log('Token: ', token); 27 | eBay.OAuth2.setCredentials(token); 28 | 29 | eBay.sell.fulfillment.getOrder('12-12345-12345').then(order => { 30 | console.log('order', JSON.stringify(order, null, 2)); 31 | }).catch(e => { 32 | console.log('error', {error: e.message}); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /examples/traditional/trading.UploadSiteHostedPictures.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-console 2 | import FormData from 'form-data'; 3 | import * as fs from 'fs'; 4 | import * as path from 'path'; 5 | import eBayApi from '../../src/eBayApi.js'; 6 | 7 | const eBay = eBayApi.fromEnv(); 8 | 9 | (async () => { 10 | try { 11 | const image = fs.readFileSync(path.resolve(__dirname, 'upload_ok.png')); 12 | 13 | // const image = fs.readFileSync(path.resolve(__dirname, 'upload_bad_quality.jpg')); 14 | // --> To reduce possible issues with picture display quality, eBay recommends that pictures you upload have a JPEG quality value of 90 or greater. 15 | const response = await eBay.trading.UploadSiteHostedPictures({ 16 | ExtensionInDays: 1, 17 | }, { 18 | hook: (xml: string) => { 19 | const form = new FormData(); 20 | // XML should be always first 21 | form.append('XML Payload', xml, 'payload.xml'); 22 | form.append('dummy', image) 23 | return { 24 | body: form, 25 | headers: form.getHeaders() 26 | } 27 | } 28 | }); 29 | 30 | console.log(response); 31 | } catch (error) { 32 | console.log(JSON.stringify(error, null, 2)); 33 | } 34 | })(); -------------------------------------------------------------------------------- /src/types/traditional/add-items-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/AddItems.html#Output 2 | import type { CurrencyCodeType, StandardOutputFields } from './common.js'; 3 | 4 | export interface AddItemsResponse extends StandardOutputFields { 5 | AddItemResponseContainer: { 6 | Category2ID?: string; 7 | CategoryID?: string; 8 | CorrelationID: string; 9 | DiscountReason?: 'CustomCode' | 'Promotion' | 'SpecialOffer'; 10 | EndTime: string; 11 | Errors?: { 12 | ErrorClassification?: 'CustomCode' | 'RequestError' | 'SystemError'; 13 | ErrorCode?: string; 14 | ErrorParameters?: { 15 | Value?: string; 16 | }; 17 | LongMessage?: string; 18 | SeverityCode?: 'CustomCode' | 'Error' | 'Warning'; 19 | ShortMessage?: string; 20 | UserDisplayHint?: boolean; 21 | }; 22 | Fees: { 23 | Fee: { 24 | Fee: number | { value: number; currencyID: CurrencyCodeType }; 25 | Name: string; 26 | PromotionalDiscount: 27 | | number 28 | | { value: number; currencyID: CurrencyCodeType }; 29 | }; 30 | }; 31 | ItemID: string; 32 | Message?: string; 33 | StartTime: string; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /src/api/traditional/clientAlerts/types.ts: -------------------------------------------------------------------------------- 1 | enum EventType { 2 | AskSellerQuestion = 'AskSellerQuestion', 3 | BestOffer = 'BestOffer', 4 | BestOfferDeclined = 'BestOfferDeclined', 5 | BestOfferPlaced = 'BestOfferPlaced', 6 | BidPlaced = 'BidPlaced', 7 | BidReceived = 'BidReceived', 8 | CounterOfferReceived = 'CounterOfferReceived', 9 | CustomCode = 'CustomCode', 10 | EndOfAuction = 'EndOfAuction', 11 | FeedbackLeft = 'FeedbackLeft', 12 | FeedbackReceived = 'FeedbackReceived', 13 | FeedbackStarChanged = 'FeedbackStarChanged', 14 | FixedPriceEndOfTransaction = 'FixedPriceEndOfTransaction', 15 | FixedPriceTransaction = 'FixedPriceTransaction', 16 | ItemAddedToWatchList = 'ItemAddedToWatchList', 17 | ItemEnded = 'ItemEnded', 18 | ItemListed = 'ItemListed', 19 | ItemLost = 'ItemLost', 20 | ItemMarkedPaid = 'ItemMarkedPaid', 21 | ItemMarkedShipped = 'ItemMarkedShipped', 22 | ItemRemovedFromWatchList = 'ItemRemovedFromWatchList', 23 | ItemSold = 'ItemSold', 24 | ItemUnsold = 'ItemUnsold', 25 | ItemWon = 'ItemWon', 26 | OutBid = 'OutBid', 27 | PriceChange = 'PriceChange', 28 | SecondChanceOffer = 'SecondChanceOffer', 29 | WatchedItemEndingSoon = 'WatchedItemEndingSoon' 30 | } 31 | 32 | export {EventType}; 33 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import terser from '@rollup/plugin-terser'; 2 | import resolve from '@rollup/plugin-node-resolve'; 3 | import commonjs from '@rollup/plugin-commonjs'; 4 | import json from '@rollup/plugin-json'; 5 | import bundleSize from 'rollup-plugin-bundle-size'; 6 | import virtual from '@rollup/plugin-virtual'; 7 | 8 | const pkg = require('./package.json'); 9 | 10 | const plugins = [ 11 | virtual({ 12 | crypto: `export function createHash() { throw Error('crypto.createHash is not supported in browser.'); }; export function sign() { throw Error('crypto.sign is not supported in browser.'); };`, 13 | }), 14 | bundleSize(), 15 | resolve({ 16 | browser: true 17 | }), 18 | json(), 19 | commonjs(), 20 | terser({ 21 | keep_fnames: true 22 | }), 23 | ] 24 | 25 | export default [{ 26 | input: './lib/index.js', 27 | output: [ 28 | { 29 | file: pkg.browser, 30 | format: 'umd', 31 | name: 'eBayApi', 32 | exports: 'default', 33 | sourcemap: false, 34 | }, 35 | ], 36 | plugins 37 | }, { 38 | input: './dist/eBayApi.js', 39 | output: [ 40 | { 41 | file: pkg['browser:esm'], 42 | format: 'esm', 43 | exports: 'named' 44 | }, 45 | ], 46 | context: 'window', 47 | plugins 48 | }] 49 | -------------------------------------------------------------------------------- /src/types/traditional/place-offer-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/PlaceOffer.html#Output 2 | import type { 3 | CurrencyCodeType, 4 | StandardOutputFields, 5 | } from './common.js'; 6 | 7 | export interface PlaceOfferResponse extends StandardOutputFields { 8 | BestOffer: { 9 | BestOfferID?: string; 10 | Status?: 11 | | 'Accepted' 12 | | 'Active' 13 | | 'AdminEnded' 14 | | 'All' 15 | | 'Countered' 16 | | 'CustomCode' 17 | | 'Declined' 18 | | 'Expired' 19 | | 'Pending' 20 | | 'PendingBuyerConfirmation' 21 | | 'PendingBuyerPayment' 22 | | 'Retracted' 23 | | 'SellerAccept'; 24 | }; 25 | OrderLineItemID?: string; 26 | SellingStatus: { 27 | ConvertedCurrentPrice?: 28 | | number 29 | | { value: number; currencyID: CurrencyCodeType }; 30 | CurrentPrice: number | { value: number; currencyID: CurrencyCodeType }; 31 | HighBidder?: { 32 | UserID?: string; 33 | }; 34 | MinimumToBid?: number | { value: number; currencyID: CurrencyCodeType }; 35 | ReserveMet?: boolean; 36 | SuggestedBidValues?: { 37 | BidValue?: number | { value: number; currencyID: CurrencyCodeType }; 38 | }; 39 | }; 40 | TransactionID?: string; 41 | } 42 | -------------------------------------------------------------------------------- /test/api/errors/errors.json: -------------------------------------------------------------------------------- 1 | { 2 | "traditional": { 3 | "Timestamp": "2021-10-23T19:11:42.335Z", 4 | "Ack": "Failure", 5 | "Errors": { 6 | "ShortMessage": "Error Message", 7 | "LongMessage": "description", 8 | "ErrorCode": 930, 9 | "SeverityCode": "Error", 10 | "ErrorClassification": "RequestError" 11 | }, 12 | "Version": 1177, 13 | "Build": "E1177_CORE_APIMSG_19110890_R1" 14 | }, 15 | "restful": { 16 | "errors": [ 17 | { 18 | "errorId": 1, 19 | "domain": "domain", 20 | "severity": "ERROR", 21 | "category": "REQUEST", 22 | "message": "Error Message", 23 | "parameter": [ 24 | { 25 | "value": "value", 26 | "name": "name" 27 | } 28 | ], 29 | "longMessage": "description", 30 | "inputRefIds": [], 31 | "httpStatusCode": 400 32 | } 33 | ] 34 | }, 35 | "oauth": { 36 | "error": "Error Message", 37 | "error_description": "description" 38 | }, 39 | "postOrder": { 40 | "errorMessage": { 41 | "error": { 42 | "errorId": 1, 43 | "domain": "domain", 44 | "severity": "ERROR", 45 | "category": "REQUEST", 46 | "message": "Error Message" 47 | } 48 | } 49 | }, 50 | "plain": "Error Message" 51 | } -------------------------------------------------------------------------------- /src/types/traditional/get-ad-format-leads-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetAdFormatLeads.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface GetAdFormatLeadsResponse extends StandardOutputFields { 5 | AdFormatLead: { 6 | AdditionalInformation?: string; 7 | Address?: { 8 | CityName?: string; 9 | FirstName?: string; 10 | LastName?: string; 11 | Phone?: string; 12 | Phone2?: string; 13 | PostalCode?: string; 14 | StateOrProvince?: string; 15 | Street1?: string; 16 | }; 17 | Answer1?: boolean; 18 | Answer2?: boolean; 19 | BestTimeToCall?: string; 20 | Email?: string; 21 | ExternalEmail?: string; 22 | FinancingAnswer?: boolean; 23 | ItemID?: string; 24 | ItemTitle?: string; 25 | MemberMessage?: { 26 | MemberMessageExchange?: { 27 | CreationDate?: string; 28 | Question?: { 29 | Body?: string; 30 | }; 31 | Response?: string; 32 | }; 33 | }; 34 | PurchaseTimeFrame?: string; 35 | Status?: 'CustomCode' | 'New' | 'Responded'; 36 | SubmittedTime?: string; 37 | TradeInMake?: string; 38 | TradeInModel?: string; 39 | TradeInYear?: string; 40 | UserID?: string; 41 | }; 42 | AdFormatLeadCount: number; 43 | } 44 | -------------------------------------------------------------------------------- /src/api/restful/buy/offer/index.ts: -------------------------------------------------------------------------------- 1 | import {PlaceProxyBidRequest} from '../../../../types/index.js'; 2 | import {operations} from '../../../../types/restful/specs/buy_offer_v1_beta_oas3.js'; 3 | import Restful, {OpenApi} from '../../index.js'; 4 | 5 | /** 6 | * The Api Offer API enables Partners to place proxy bids for a buyer and retrieve the auctions where the buyer is 7 | * bidding. Client Credentials: https://api.ebay.com/oauth/api_scope/buy.offer.auction 8 | */ 9 | export default class Offer extends Restful implements OpenApi { 10 | 11 | static id = 'Offer'; 12 | 13 | get basePath(): string { 14 | return '/buy/offer/v1_beta'; 15 | } 16 | 17 | /** 18 | * This method retrieves the bidding details that are specific to the buyer of the specified auction. 19 | * 20 | * @param itemId 21 | */ 22 | public getBidding(itemId: string) { 23 | const id = encodeURIComponent(itemId); 24 | return this.get(`/bidding/${id}`); 25 | } 26 | 27 | /** 28 | * This method uses a user access token to place a proxy bid for the buyer on a specific auction item. 29 | * 30 | * @param itemId 31 | * @param {PlaceProxyBidRequest} body 32 | */ 33 | public placeProxyBid(itemId: string, body?: PlaceProxyBidRequest) { 34 | const id = encodeURIComponent(itemId); 35 | return this.post(`/bidding/${id}/place_proxy_bid`, body); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/api/restful/sell/index.ts: -------------------------------------------------------------------------------- 1 | import AccountV1 from './account/v1.js'; 2 | import AccountV2 from './account/v2.js'; 3 | import Analytics from './analytics/index.js'; 4 | import Compliance from './compliance/index.js'; 5 | import Finances from './finances/index.js'; 6 | import Fulfillment from './fulfillment/index.js'; 7 | import Inventory from './inventory/index.js'; 8 | import Marketing from './marketing/index.js'; 9 | import Metadata from './metadata/index.js'; 10 | import Recommendation from './recommendation/index.js'; 11 | import Feed from './feed/index.js'; 12 | import Logistics from './logistics/index.js'; 13 | import Negotiation from './negotiation/index.js'; 14 | import Listing from './listing/index.js'; 15 | 16 | export type Sell = { 17 | account: AccountV1, 18 | accountV2: AccountV2, 19 | analytics: Analytics, 20 | compliance: Compliance, 21 | fulfillment: Fulfillment, 22 | inventory: Inventory, 23 | marketing: Marketing, 24 | metadata: Metadata, 25 | recommendation: Recommendation, 26 | finances: Finances 27 | feed: Feed, 28 | logistics: Logistics, 29 | negotiation: Negotiation, 30 | listing: Listing 31 | }; 32 | 33 | export { 34 | AccountV1, 35 | AccountV2, 36 | Compliance, 37 | Analytics, 38 | Fulfillment, 39 | Inventory, 40 | Marketing, 41 | Metadata, 42 | Recommendation, 43 | Finances, 44 | Feed, 45 | Logistics, 46 | Negotiation, 47 | Listing 48 | }; 49 | -------------------------------------------------------------------------------- /src/api/restful/developer/keyManagement/index.ts: -------------------------------------------------------------------------------- 1 | import {operations} from '../../../../types/restful/specs/developer_key_management_v1_oas3.js'; 2 | import Restful, {OpenApi} from '../../index.js'; 3 | 4 | /** 5 | * This method retrieves the call limit and utilization data for an application. 6 | */ 7 | export default class KeyManagement extends Restful implements OpenApi { 8 | 9 | static id = 'KeyManagement'; 10 | 11 | get subdomain(): string { 12 | return 'apiz'; 13 | } 14 | 15 | get basePath(): string { 16 | return '/developer/key_management/v1'; 17 | } 18 | 19 | /** 20 | * This method returns the Public Key, Public Key as JWE, 21 | * and metadata for all keypairs associated with the application key making the call. 22 | */ 23 | public getSigningKeys() { 24 | return this.get(`/signing_key`); 25 | } 26 | 27 | /** 28 | * This method creates keypairs. 29 | */ 30 | public createSigningKey(signingKeyCipher: 'ED25519' | 'RSA') { 31 | return this.post(`/signing_key`, { 32 | signingKeyCipher 33 | }); 34 | } 35 | 36 | /** 37 | * This method returns the Public Key, Public Key as JWE, 38 | * and metadata for a specified signingKeyId associated with the application key making the call. 39 | * @param signingKeyId the signin key 40 | */ 41 | public getSigningKey(signingKeyId: string) { 42 | return this.get(`/signing_key/${signingKeyId}`); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/types/apiTypes.ts: -------------------------------------------------------------------------------- 1 | import {AxiosRequestConfig} from 'axios'; 2 | import {Locale, MarketplaceId, SiteId} from '../enums/index.js'; 3 | 4 | export type Scope = string[]; 5 | 6 | export type Keyset = { 7 | appId: string, // (Client ID) 8 | certId: string, // (Client Secret) 9 | devId?: string, 10 | }; 11 | 12 | export type RestConfig = { 13 | marketplaceId?: MarketplaceId | `${MarketplaceId}`, 14 | endUserCtx?: string, 15 | contentLanguage?: Locale | `${Locale}` 16 | acceptLanguage?: Locale | `${Locale}` 17 | } 18 | 19 | export type TraditionalConfig = { 20 | siteId?: SiteId | `${SiteId}` 21 | authToken?: string | null 22 | } 23 | 24 | export type Cipher = 'sha256' | 'sha512'; 25 | 26 | export type Signature = { 27 | cipher?: Cipher 28 | jwe: string, // The value of the x-ebay-signature-key header is the Public Key as JWE value that has been created by the Key Management API. 29 | privateKey: string 30 | } 31 | 32 | export type eBayConfig = Keyset & { 33 | sandbox: boolean, 34 | ruName?: string, 35 | scope?: Scope, 36 | signature?: Signature | null 37 | } & TraditionalConfig & RestConfig; 38 | 39 | export type ApiConfig = { 40 | autoRefreshToken?: boolean, 41 | axiosConfig?: AxiosRequestConfig 42 | } 43 | 44 | export type Headers = Record; 45 | 46 | export type ApiRequestConfig = { 47 | headers?: Headers, 48 | returnResponse?: boolean 49 | } 50 | 51 | export type AppConfig = eBayConfig & ApiConfig; 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/types/traditional/get-member-messages-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetMemberMessages.html#Output 2 | import type { 3 | CurrencyCodeType, 4 | StandardOutputFields, 5 | } from './common.js'; 6 | 7 | export interface GetMemberMessagesResponse extends StandardOutputFields { 8 | MemberMessage?: { 9 | MemberMessageExchange?: { 10 | Item?: { 11 | ItemID?: string; 12 | ListingDetails?: { 13 | EndTime?: string; 14 | StartTime?: string; 15 | }; 16 | SellingStatus?: { 17 | CurrentPrice?: 18 | | number 19 | | { value: number; currencyID: CurrencyCodeType }; 20 | }; 21 | Title?: string; 22 | }; 23 | LastModifiedDate?: string; 24 | MessageMedia?: { 25 | MediaName?: string; 26 | MediaURL?: string; 27 | }; 28 | MessageStatus?: 'Answered' | 'CustomCode' | 'Unanswered'; 29 | Question?: { 30 | Body?: string; 31 | DisplayToPublic?: boolean; 32 | MessageID?: string; 33 | MessageMedia?: { 34 | MediaName?: string; 35 | MediaURL?: string; 36 | }; 37 | MessageType?: any; 38 | QuestionType?: any; 39 | RecipientID?: string; 40 | SenderEmail?: string; 41 | SenderID?: string; 42 | Subject?: string; 43 | }; 44 | Response?: string; 45 | }; 46 | }; 47 | PaginationResult: { 48 | TotalNumberOfEntries: number; 49 | TotalNumberOfPages: number; 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /src/api/restful/sell/negotiation/index.ts: -------------------------------------------------------------------------------- 1 | import {operations} from '../../../../types/restful/specs/sell_negotiation_v1_oas3.js'; 2 | import Restful, {OpenApi} from '../../index.js'; 3 | 4 | /** 5 | * The Negotiations API gives sellers the ability to proactively send discount offers to buyers who have shown an "interest" in their listings. 6 | */ 7 | export default class Negotiation extends Restful implements OpenApi { 8 | 9 | static id = 'Negotiation'; 10 | 11 | get basePath(): string { 12 | return '/sell/negotiation/v1'; 13 | } 14 | 15 | /** 16 | * This method evaluates a seller's current listings and returns the set of IDs that are eligible for a seller-initiated discount offer to a buyer. 17 | * 18 | * @param limit This query parameter specifies the maximum number of items to return from the result set on a page in the paginated response. 19 | * @param offset This query parameter specifies the number of results to skip in the result set before returning the first result in the paginated response. 20 | */ 21 | public findEligibleItems({limit, offset}: { limit?: string, offset?: string } = {}) { 22 | return this.get(`/find_eligible_items`, { 23 | params: { 24 | limit, 25 | offset 26 | } 27 | }); 28 | } 29 | 30 | /** 31 | * This method sends eligible buyers offers to purchase items in a listing at a discount. 32 | * 33 | * @param data The CreateOffersRequest 34 | */ 35 | public sendOfferToInterestedBuyers(data: any) { 36 | return this.post(`/send_offer_to_interested_buyers`, data); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/api/index.ts: -------------------------------------------------------------------------------- 1 | import Auth from '../auth/index.js'; 2 | import {IEBayApiRequest} from '../request.js'; 3 | import {AppConfig} from '../types/index.js'; 4 | import Base from './base.js'; 5 | import { 6 | generateContentDigestValue, 7 | generateSignature, 8 | generateSignatureInput, 9 | getUnixTimestamp, 10 | SignatureComponents 11 | } from './digitalSignature.js'; 12 | 13 | /** 14 | * Superclass with Auth container. 15 | */ 16 | export default abstract class Api extends Base { 17 | public readonly auth: Auth; 18 | 19 | constructor( 20 | config: AppConfig, 21 | req?: IEBayApiRequest, 22 | auth?: Auth 23 | ) { 24 | super(config, req); 25 | this.auth = auth || new Auth(this.config, this.req); 26 | } 27 | 28 | getDigitalSignatureHeaders(signatureComponents: SignatureComponents, payload: any) { 29 | if (!this.config.signature) { 30 | return {}; 31 | } 32 | 33 | const timestamp = getUnixTimestamp() 34 | 35 | const digitalSignatureHeaders = { 36 | 'x-ebay-enforce-signature': true, // enable digital signature validation 37 | 'x-ebay-signature-key': this.config.signature.jwe, // always contains JWE 38 | ...payload ? { 39 | 'content-digest': generateContentDigestValue(payload, this.config.signature.cipher ?? 'sha256') 40 | } : {}, 41 | 'signature-input': generateSignatureInput(payload, timestamp) 42 | }; 43 | 44 | return { 45 | ...digitalSignatureHeaders, 46 | 'signature': generateSignature(digitalSignatureHeaders, this.config.signature.privateKey, signatureComponents, payload, timestamp) 47 | }; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /test/api/restful/sell/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AccountV1, 3 | AccountV2, 4 | Analytics, 5 | Compliance, 6 | Feed, 7 | Finances, 8 | Fulfillment, 9 | Inventory, 10 | Listing, 11 | Logistics, 12 | Marketing, 13 | Metadata, 14 | Negotiation, 15 | Recommendation 16 | } from '../../../../src/api/restful/sell/index.js'; 17 | import {readSpecs} from '../../jsonfile.js'; 18 | 19 | const tests = new Map(); 20 | tests.set(AccountV1, readSpecs( 'sell_account_v1_oas3.json', import.meta.url)); 21 | tests.set(AccountV2, readSpecs( 'sell_account_v2_oas3.json', import.meta.url)); 22 | tests.set(Analytics, readSpecs( 'sell_analytics_v1_oas3.json', import.meta.url)); 23 | tests.set(Compliance, readSpecs( 'sell_compliance_v1_oas3.json', import.meta.url)); 24 | tests.set(Fulfillment, readSpecs( 'sell_fulfillment_v1_oas3.json', import.meta.url)); 25 | tests.set(Inventory, readSpecs( 'sell_inventory_v1_oas3.json', import.meta.url)); 26 | tests.set(Marketing, readSpecs( 'sell_marketing_v1_oas3.json', import.meta.url)); 27 | tests.set(Metadata, readSpecs( 'sell_metadata_v1_oas3.json', import.meta.url)); 28 | tests.set(Recommendation, readSpecs( 'sell_recommendation_v1_oas3.json', import.meta.url)); 29 | tests.set(Finances, readSpecs( 'sell_finances_v1_oas3.json', import.meta.url)); 30 | tests.set(Feed, readSpecs( 'sell_feed_v1_oas3.json', import.meta.url)); 31 | tests.set(Logistics, readSpecs( 'sell_logistics_v1_oas3.json', import.meta.url)); 32 | tests.set(Negotiation, readSpecs( 'sell_negotiation_v1_oas3.json', import.meta.url)); 33 | tests.set(Listing, readSpecs( 'sell_listing_v1_beta_oas3.json', import.meta.url)); 34 | 35 | export default tests; 36 | -------------------------------------------------------------------------------- /src/api/restful/developer/analytics/index.ts: -------------------------------------------------------------------------------- 1 | import {operations} from '../../../../types/restful/specs/developer_analytics_v1_beta_oas3.js'; 2 | import Restful, {OpenApi} from '../../index.js'; 3 | 4 | /** 5 | * This method retrieves the call limit and utilization data for an application. 6 | */ 7 | export default class Analytics extends Restful implements OpenApi { 8 | 9 | static id = 'Analytics'; 10 | 11 | get basePath(): string { 12 | return '/developer/analytics/v1_beta'; 13 | } 14 | 15 | /** 16 | * This method retrieves the call limit and utilization data for an application. 17 | * 18 | * @param apiContext This optional query parameter filters the result to include only the specified API context. 19 | * @param apiName This optional query parameter filters the result to include only the APIs specified. 20 | */ 21 | public getRateLimits(apiContext?: string, apiName?: string) { 22 | return this.get(`/rate_limit/`, { 23 | params: { 24 | api_context: apiContext, 25 | api_name: apiName 26 | } 27 | }); 28 | } 29 | 30 | /** 31 | * This method retrieves the call limit and utilization data for an application user. 32 | * 33 | * @param apiContext This optional query parameter filters the result to include only the specified API context. 34 | * @param apiName This optional query parameter filters the result to include only the APIs specified. 35 | */ 36 | public getUserRateLimits(apiContext: string, apiName: string) { 37 | return this.get(`/user_rate_limit/`, { 38 | params: { 39 | api_context: apiContext, 40 | api_name: apiName 41 | } 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/api/restful/sell/recommendation/index.ts: -------------------------------------------------------------------------------- 1 | import {FindListingRecommendationRequest} from '../../../../types/index.js'; 2 | import {operations} from '../../../../types/restful/specs/sell_recommendation_v1_oas3.js'; 3 | import Restful, {OpenApi} from '../../index.js'; 4 | 5 | 6 | /** 7 | * The Recommendation API returns information that sellers can use to optimize the configuration of their 8 | * listings on eBay. 9 | */ 10 | export default class Recommendation extends Restful implements OpenApi { 11 | 12 | static id = 'Recommendation'; 13 | 14 | get basePath(): string { 15 | return '/sell/recommendation/v1'; 16 | } 17 | 18 | /** 19 | * The find method returns recommendations and information that sellers can use to optimize their listing 20 | * configurations. 21 | * 22 | * @param filter Provide a list of key-value pairs to specify the criteria you want to use to filter the response. 23 | * @param limit Use this query parameter to set the maximum number of ads to return on a page from the paginated 24 | * response. Default: 10 Maximum: 500 25 | * @param offset Specifies the number of ads to skip in the result set before returning the first ad in the 26 | * paginated response. 27 | * @param body FindListingRecommendationRequest 28 | */ 29 | public findListingRecommendations({filter, limit, offset}: { filter?: string, limit?: number, offset?: number } = {}, 30 | body?: FindListingRecommendationRequest 31 | ) { 32 | return this.post(`/find`, { 33 | data: body, 34 | params: { 35 | filter, 36 | limit, 37 | offset 38 | } 39 | }); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/types/traditional/get-my-messages-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetMyMessages.html#Output 2 | import type { StandardOutputFields } from './common.js'; 3 | 4 | export interface GetMyMessagesResponse extends StandardOutputFields { 5 | Messages: { 6 | Message?: { 7 | Content?: string; 8 | ExpirationDate?: string; 9 | ExternalMessageID?: string; 10 | Flagged?: boolean; 11 | Folder?: { 12 | FolderID?: bigint; 13 | }; 14 | HighPriority?: boolean; 15 | ItemEndTime?: string; 16 | ItemID?: string; 17 | ItemTitle?: string; 18 | ListingStatus?: any; 19 | MessageID?: string; 20 | MessageMedia?: { 21 | MediaName?: string; 22 | MediaURL?: string; 23 | }; 24 | MessageType?: any; 25 | QuestionType?: any; 26 | Read?: boolean; 27 | ReceiveDate?: string; 28 | RecipientUserID?: string; 29 | Replied?: boolean; 30 | ResponseDetails?: { 31 | ResponseEnabled?: boolean; 32 | ResponseURL?: string; 33 | }; 34 | SendToName?: string; 35 | Sender?: string; 36 | Subject?: string; 37 | Text?: string; 38 | }; 39 | }; 40 | Summary?: { 41 | FlaggedMessageCount?: number; 42 | FolderSummary?: { 43 | FolderID?: bigint; 44 | FolderName?: string; 45 | NewHighPriorityCount?: number; 46 | NewMessageCount?: number; 47 | TotalHighPriorityCount?: number; 48 | TotalMessageCount?: number; 49 | }; 50 | NewHighPriorityCount?: number; 51 | NewMessageCount?: number; 52 | TotalHighPriorityCount?: number; 53 | TotalMessageCount?: number; 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /src/api/restful/commerce/media/index.ts: -------------------------------------------------------------------------------- 1 | import {CreateVideoRequest, InputStream} from '../../../../types/index.js'; 2 | import {operations} from '../../../../types/restful/specs/commerce_media_v1_beta_oas3.js'; 3 | import Restful, {OpenApi} from '../../index.js'; 4 | 5 | /** 6 | * The Media API allows sellers to create, upload, and fetch videos. 7 | */ 8 | export default class Media extends Restful implements OpenApi { 9 | 10 | 11 | static id = 'Media'; 12 | 13 | get basePath(): string { 14 | return '/commerce/media/v1_beta'; 15 | } 16 | 17 | get subdomain(): string { 18 | return 'apim'; 19 | } 20 | 21 | /** 22 | * This method creates a video. When using this method, specify the title, size, and classification of the video to be created. 23 | * @param body the CreateVideoRequest 24 | */ 25 | async createVideo(body?: CreateVideoRequest) { 26 | return this.post('/video', body); 27 | } 28 | 29 | /** 30 | * This method retrieves a video's metadata and content given a specified video ID. 31 | * @param videoId The unique identifier of the video to be retrieved. 32 | */ 33 | async getVideo(videoId: string) { 34 | videoId = encodeURIComponent(videoId); 35 | return this.get(`/video/${videoId}`); 36 | }; 37 | 38 | /** 39 | * This method associates the specified file with the specified video ID and uploads the input file. 40 | * 41 | * @param videoId The unique identifier of the video to be uploaded. 42 | * @param body The request payload for this method is the input stream for the video source. The input source must be an .mp4 file of the type MPEG-4 Part 10 or Advanced Video Coding (MPEG-4 AVC). 43 | */ 44 | async uploadVideo(videoId: string, body?: InputStream) { 45 | videoId = encodeURIComponent(videoId); 46 | return this.post(`/video/${videoId}/upload`, body); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/api/restful/buy/marketing/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | BuyMarketingGetAlsoBoughtByProductParams, 3 | BuyMarketingGetAlsoViewedByProductParams, 4 | BuyMarketingGetMerchandisedProductsParams 5 | } from '../../../../types/index.js'; 6 | import {operations} from '../../../../types/restful/specs/buy_marketing_v1_beta_oas3.js'; 7 | import Restful, {OpenApi} from '../../index.js'; 8 | 9 | /** 10 | * The Marketing API retrieves eBay products based on a metric, such as Best Selling, as well as products that were 11 | * also bought and also viewed. 12 | */ 13 | export default class Marketing extends Restful implements OpenApi { 14 | 15 | static id = 'Marketing'; 16 | 17 | get basePath(): string { 18 | return '/buy/marketing/v1_beta'; 19 | } 20 | 21 | // 22 | // Marketing 23 | // Client Credentials: https://api.ebay.com/oauth/api_scope/buy.marketing 24 | // 25 | 26 | /** 27 | * This call returns products that were also bought when shoppers bought the product specified in the request. 28 | * @param params 29 | */ 30 | public getAlsoBoughtByProduct(params: BuyMarketingGetAlsoBoughtByProductParams) { 31 | return this.get(`/merchandised_product/get_also_bought_products`, { 32 | params 33 | }); 34 | } 35 | 36 | /** 37 | * This call returns products that were also viewed when shoppers viewed the product specified in the request. 38 | * 39 | * @param params 40 | */ 41 | public getAlsoViewedByProduct(params: BuyMarketingGetAlsoViewedByProductParams) { 42 | return this.get(`/merchandised_product/get_also_viewed_products`, { 43 | params 44 | }); 45 | } 46 | 47 | /** 48 | * This call returns an array of products based on the category and metric specified. 49 | * 50 | * @param params 51 | */ 52 | public getMerchandisedProducts(params: BuyMarketingGetMerchandisedProductsParams) { 53 | return this.get(`/merchandised_product`, { 54 | params 55 | }); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /test/api/errors/errors.spec.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai'; 2 | import { 3 | checkEBayTraditionalResponse, 4 | EbayApiError, 5 | EBayApiError, 6 | EBayError, 7 | extractEBayError, 8 | handleEBayError 9 | } from '../../../src/errors/index.js'; 10 | import {readJSONSync} from '../jsonfile.js'; 11 | 12 | describe('eBay Errors', () => { 13 | const errors = readJSONSync('./errors.json', import.meta.url); 14 | 15 | Object.entries(errors).forEach(([key, payload]: [string, any]) => { 16 | it('maps errors correctly for ' + key, () => { 17 | const result = { 18 | response: { 19 | data: payload 20 | } 21 | }; 22 | 23 | const {message, description} = extractEBayError(result); 24 | expect(message).to.equal('Error Message'); 25 | if (description) { 26 | expect(description).to.equal('description'); 27 | } 28 | }); 29 | }); 30 | 31 | it('Throw correct error chain', () => { 32 | expect(() => handleEBayError({ 33 | response: { 34 | data: errors.traditional 35 | } 36 | })).to.throw(EBayApiError).with.property('errorCode', 930); 37 | 38 | expect(() => handleEBayError({ 39 | response: { 40 | data: errors.oauth 41 | } 42 | })).to.throw(EbayApiError); 43 | expect(() => handleEBayError({ 44 | response: { 45 | data: errors.restful 46 | } 47 | })).to.throw(EBayError) 48 | .with.property('errorCode', 1); 49 | }); 50 | 51 | it('Does not throw if the error is warning', () => { 52 | expect(() => checkEBayTraditionalResponse({}, { 53 | 'Timestamp': '2021-10-23T19:11:42.335Z', 54 | 'Ack': 'Warning', 55 | 'Errors': { 56 | 'ShortMessage': 'Error Message', 57 | 'LongMessage': 'description', 58 | 'ErrorCode': 930, 59 | 'SeverityCode': 'Error', 60 | 'ErrorClassification': 'RequestError' 61 | }, 62 | 'Version': 1177, 63 | 'Build': 'E1177_CORE_APIMSG_19110890_R1' 64 | })).to.not.throw(); 65 | }) 66 | 67 | }); -------------------------------------------------------------------------------- /src/api/restful/sell/account/v2.ts: -------------------------------------------------------------------------------- 1 | import {RateTableUpdate, UpdatePayoutPercentageRequest} from '../../../../types/index.js'; 2 | import {operations} from '../../../../types/restful/specs/sell_account_v2_oas3.js'; 3 | 4 | import Restful, {OpenApi} from '../../index.js'; 5 | 6 | /** 7 | * This API allows sellers to retrieve and manage their custom shipping rate tables. 8 | */ 9 | export default class AccountV2 extends Restful implements OpenApi { 10 | static id = 'AccountV2'; 11 | 12 | get basePath(): string { 13 | return '/sell/account/v2'; 14 | } 15 | 16 | /** 17 | * This method retrieves an existing rate table identified by the rate_table_id path parameter. 18 | * @param rateTableId This path parameter is the unique identifier for the shipping rate table to retrieve. 19 | */ 20 | public getRateTable(rateTableId: string) { 21 | rateTableId = encodeURIComponent(rateTableId); 22 | return this.get(`/rate_table/${rateTableId}`); 23 | } 24 | 25 | /** 26 | * Request to update the shipping costs for the identified shipping rate table. 27 | * @param rateTableId This path parameter is the unique identifier for the shipping rate table to update. 28 | * @param body This request payload contains the shipping costs to update for the rate table. 29 | */ 30 | public updateShippingCost(rateTableId: string, body: RateTableUpdate) { 31 | rateTableId = encodeURIComponent(rateTableId); 32 | return this.post(`/rate_table/${rateTableId}/update_shipping_cost`, body); 33 | } 34 | 35 | /** 36 | * This method returns details on two payment instruments defined on a seller's account, including the ID, type, status, nickname, last four digits of the account number, and payout percentage for the instruments. 37 | */ 38 | public getPayoutSettings() { 39 | return this.get('/payout_settings'); 40 | } 41 | 42 | /** 43 | * This method allows sellers in mainland China to configure the split-payout percentage for two payout instruments available for seller payouts. For example, a seller can split payouts to have 70% of the payout go to a bank account and 30% go to a Payoneer account. 44 | * @param body 45 | */ 46 | public updatePayoutPercentage(body: UpdatePayoutPercentageRequest) { 47 | return this.post(`/payout_settings/update_percentage`, body); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/api/restful/sell/compliance/index.ts: -------------------------------------------------------------------------------- 1 | import {SuppressViolationRequest} from '../../../../types/index.js'; 2 | import {operations} from '../../../../types/restful/specs/sell_compliance_v1_oas3.js'; 3 | import Restful, {OpenApi} from '../../index.js'; 4 | 5 | /** 6 | * Service for providing the compliance violations of seller account/listings 7 | */ 8 | export default class Compliance extends Restful implements OpenApi { 9 | 10 | static id = 'Compliance'; 11 | 12 | get basePath(): string { 13 | return '/sell/compliance/v1'; 14 | } 15 | 16 | /** 17 | * This call returns listing violation counts for a seller. 18 | * 19 | * @param complianceType A user passes in one or more compliance type values through this query parameter. 20 | */ 21 | public getListingViolationsSummary(complianceType?: string) { 22 | return this.get(`/listing_violation_summary`, { 23 | params: { 24 | compliance_type: complianceType 25 | } 26 | }); 27 | } 28 | 29 | /** 30 | * This call returns specific listing violations for five different compliance types. 31 | * 32 | * @param complianceType A user passes in one or more compliance type values through this query parameter. 33 | * @param offset The first policy violation to return based on its position in the collection of listing 34 | * violations. 35 | * @param listingId 36 | * @param limit This query parameter is used if the user wants to set a limit on the number of listing violations 37 | * that are returned in the current result set. 38 | */ 39 | public getListingViolations({complianceType, offset, listingId, limit}: 40 | { complianceType?: string, offset?: number, listingId?: string, limit?: number } = {}) { 41 | return this.get(`/listing_violation`, { 42 | params: { 43 | compliance_type: complianceType, 44 | offset, 45 | listing_id: listingId, 46 | limit 47 | } 48 | }); 49 | } 50 | 51 | /** 52 | * This call suppresses a listing violation for a specific listing. Only listing violations in the AT_RISK state (returned in the violations.complianceState field of the getListingViolations call) can be suppressed. 53 | * 54 | * @param body SuppressViolationRequest 55 | */ 56 | public suppressViolation(body: SuppressViolationRequest) { 57 | return this.post(`/suppress_listing_violation`, body); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/api/restful/commerce/charity/index.ts: -------------------------------------------------------------------------------- 1 | import {operations} from '../../../../types/restful/specs/commerce_charity_v1_oas3.js'; 2 | import Restful, {OpenApi} from '../../index.js'; 3 | 4 | /** 5 | * The Charity API allows third-party developers to search for and access details on supported charitable organizations. 6 | */ 7 | export default class Charity extends Restful implements OpenApi { 8 | 9 | static id = 'Charity'; 10 | 11 | get basePath(): string { 12 | return '/commerce/charity/v1'; 13 | } 14 | 15 | /** 16 | * This call is used to retrieve detailed information about supported charitable organizations. 17 | * 18 | * @param charityOrgId The unique ID of the charitable organization. 19 | */ 20 | public getCharityOrg(charityOrgId: string) { 21 | charityOrgId = encodeURIComponent(charityOrgId); 22 | return this.get(`/charity_org/${charityOrgId}`); 23 | } 24 | 25 | /** 26 | * This call is used to retrieve detailed information about supported charitable organizations. 27 | * 28 | * @param limit The number of items, from the result set, returned in a single page. Valid Values: 1-100 Default: 20 29 | * @param offset The number of items that will be skipped in the result set. 30 | * @param q A query string that matches the keywords in name, mission statement, or description. 31 | * @param registrationIds A comma-separated list of charitable organization registration IDs. 32 | */ 33 | public getCharityOrgs({ 34 | limit, 35 | offset, 36 | q, 37 | registrationIds 38 | }: { limit?: string, offset?: string, q?: string, registrationIds?: string }) { 39 | return this.get(`/charity_org`, { 40 | params: { 41 | limit, 42 | offset, 43 | q, 44 | registration_ids: registrationIds 45 | } 46 | }); 47 | } 48 | 49 | /** 50 | * This call allows users to retrieve the details for a specific charitable organization using its legacy charity ID, which has also been referred to as the charity number, external ID, and PayPal Giving Fund ID. 51 | * 52 | * @param legacyCharityOrgId The legacy ID of the charitable organization. 53 | */ 54 | public getCharityOrgByLegacyId(legacyCharityOrgId: string) { 55 | return this.get(`/charity_org/get_charity_org_by_legacy_id`, { 56 | params: { 57 | legacy_charity_org_id: legacyCharityOrgId 58 | } 59 | }); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/request.ts: -------------------------------------------------------------------------------- 1 | import axios, {AxiosInstance, AxiosRequestConfig, AxiosResponse} from 'axios'; 2 | import debug from 'debug'; 3 | import {stringify} from 'qs'; 4 | 5 | const log = debug('ebay:request'); 6 | 7 | export const defaultGlobalHeaders = { 8 | 'Access-Control-Allow-Origin': '*', 9 | 'Access-Control-Allow-Headers': 'X-Requested-With, Origin, Content-Type, X-Auth-Token', 10 | 'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE' 11 | } 12 | 13 | export const multipartHeader = { 14 | 'Content-Type': 'multipart/form-data' 15 | } 16 | 17 | export const defaultAxiosConfig: AxiosRequestConfig = { 18 | paramsSerializer: { 19 | indexes: null 20 | } 21 | } 22 | 23 | export interface IEBayApiRequest { 24 | readonly instance: T; 25 | 26 | get(url: string, config?: C): Promise; 27 | 28 | delete(url: string, config?: C): Promise; 29 | 30 | post(url: string, data?: any, config?: C): Promise; 31 | 32 | postForm(url: string, data?: any, config?: C): Promise; 33 | 34 | put(url: string, data?: any, config?: C): Promise; 35 | } 36 | 37 | export class AxiosRequest implements IEBayApiRequest { 38 | public readonly instance: AxiosInstance; 39 | 40 | constructor(config: AxiosRequestConfig = {}) { 41 | this.instance = axios.create({ 42 | headers: { 43 | ...defaultGlobalHeaders 44 | }, 45 | ...defaultAxiosConfig, 46 | ...config 47 | }); 48 | } 49 | 50 | public get(url: string, config?: AxiosRequestConfig): Promise { 51 | log('get: ' + url, config); 52 | return this.instance.get(url, config); 53 | } 54 | 55 | public post(url: string, payload?: any, config?: AxiosRequestConfig): Promise { 56 | log('post: ' + url, {payload, config}); 57 | return this.instance.post(url, payload, config); 58 | } 59 | 60 | public delete(url: string, config?: AxiosRequestConfig): Promise { 61 | log('delete: ' + url, config); 62 | return this.instance.delete(url, config); 63 | } 64 | 65 | public put(url: string, payload?: any, config?: AxiosRequestConfig): Promise { 66 | log('put: ' + url, {payload, config}); 67 | return this.instance.put(url, payload, config); 68 | } 69 | 70 | public postForm(url: string, payload?: any, config?: AxiosRequestConfig): Promise { 71 | log('postForm: ' + url); 72 | const body = stringify(payload); 73 | return this.instance.post(url, body, config); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/types/traditional/get-items-awaiting-feedback-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetItemsAwaitingFeedback.html#Output 2 | import type { 3 | AddressType, 4 | StandardOutputFields, 5 | } from './common.js'; 6 | 7 | export interface GetItemsAwaitingFeedbackResponse extends StandardOutputFields { 8 | ItemsAwaitingFeedback: { 9 | PaginationResult: { 10 | TotalNumberOfEntries: number; 11 | TotalNumberOfPages: number; 12 | }; 13 | TransactionArray: { 14 | Transaction?: { 15 | Buyer?: { 16 | UserID?: string; 17 | }; 18 | FeedbackReceived?: { 19 | CommentType?: 20 | | 'CustomCode' 21 | | 'IndependentlyWithdrawn' 22 | | 'Negative' 23 | | 'Neutral' 24 | | 'Positive' 25 | | 'Withdrawn'; 26 | }; 27 | Item?: { 28 | ItemID?: string; 29 | ListingDetails?: { 30 | EndTime?: string; 31 | }; 32 | Seller?: { 33 | AboutMePage?: boolean; 34 | BiddingSummary?: any; 35 | BusinessRole?: any; 36 | BuyerInfo?: any; 37 | BayGoodStanding?: boolean; 38 | BayWikiReadOnly?: boolean; 39 | EIASToken?: string; 40 | Email?: string; 41 | EnterpriseSeller?: boolean; 42 | FeedbackPrivate?: boolean; 43 | FeedbackRatingStar?: any; 44 | FeedbackScore?: number; 45 | IDVerified?: boolean; 46 | Membership?: any; 47 | NewUser?: boolean; 48 | PositiveFeedbackPercent?: number; 49 | QualifiesForSelling?: boolean; 50 | RegistrationAddress?: AddressType; 51 | RegistrationDate?: string; 52 | SellerInfo?: any; 53 | ShippingAddress?: AddressType; 54 | Site?: any; 55 | Status?: any; 56 | TUVLevel?: number; 57 | UniqueNegativeFeedbackCount?: number; 58 | UniqueNeutralFeedbackCount?: number; 59 | UniquePositiveFeedbackCount?: number; 60 | UserAnonymized?: boolean; 61 | UserFirstName?: string; 62 | UserID?: any; 63 | UserIDChanged?: boolean; 64 | UserIDLastChanged?: string; 65 | UserLastName?: string; 66 | UserSubscription?: any; 67 | VATID?: string; 68 | VATStatus?: any; 69 | }; 70 | Title?: string; 71 | }; 72 | OrderLineItemID?: string; 73 | TransactionID?: string; 74 | }; 75 | }; 76 | }; 77 | } 78 | -------------------------------------------------------------------------------- /src/api/restful/sell/analytics/index.ts: -------------------------------------------------------------------------------- 1 | import {Metric} from '../../../../enums/index.js'; 2 | import {operations} from '../../../../types/restful/specs/sell_analytics_v1_oas3.js'; 3 | import Restful, {OpenApi} from '../../index.js'; 4 | 5 | /** 6 | * The Analytics API provides information about a seller's business performance. 7 | */ 8 | export default class Analytics extends Restful implements OpenApi { 9 | 10 | static id = 'Analytics'; 11 | 12 | get basePath(): string { 13 | return '/sell/analytics/v1'; 14 | } 15 | 16 | /** 17 | * This call retrieves all the profiles for the associated seller. 18 | */ 19 | public findSellerStandardsProfiles() { 20 | return this.get(`/seller_standards_profile`); 21 | } 22 | 23 | /** 24 | * This call retrieves seller's profiles based on a program or cycle. 25 | * 26 | * @param program Specifies the program of the requested profile. 27 | * @param cycle Specifies the cycle of the requested profile. 28 | */ 29 | public getSellerStandardsProfile(program: string, cycle: string) { 30 | program = encodeURIComponent(program); 31 | cycle = encodeURIComponent(cycle); 32 | return this.get(`/seller_standards_profile/${program}/${cycle}`); 33 | } 34 | 35 | /** 36 | * This call returns a report that details the user-traffic a seller's listings receives. 37 | * 38 | * @param dimension Specifies the basis of the report data. 39 | * @param filter Limits the report data returned. 40 | * @param metric Specifies a comma separated list of the metrics you want included in the report. 41 | * @param sort Specifies a single metric to be sorted and whether you want to sort in ascending or descending order. 42 | */ 43 | public getTrafficReport({dimension, filter, metric, sort}: 44 | { dimension?: string, filter?: string, metric?: string | Metric | `${Metric}`, sort?: string } = {}) { 45 | return this.get(`/traffic_report`, { 46 | params: { 47 | dimension, 48 | filter, 49 | metric, 50 | sort 51 | } 52 | }); 53 | } 54 | 55 | /** 56 | * Use this method to retrieve a seller's performance and rating for the customer service metric. 57 | * 58 | * @param customerServiceMetricType Use this path parameter to specify the type of customer service metrics and benchmark data you want returned for the seller. 59 | * @param evaluationType Use this query parameter to specify the Marketplace ID to evaluate for the customer service metrics and benchmark data. 60 | */ 61 | public getCustomerServiceMetric(customerServiceMetricType: string, evaluationType: string) { 62 | return this.get(`/customer_service_metric/${customerServiceMetricType}/${evaluationType}`); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/api/restful/buy/marketplaceInsights/index.ts: -------------------------------------------------------------------------------- 1 | import {MarketingInsightsSearchParams} from '../../../../types/index.js'; 2 | import {operations} from '../../../../types/restful/specs/buy_marketplace_insights_v1_beta_oas3.js'; 3 | import Restful, {OpenApi} from '../../index.js'; 4 | 5 | /** 6 | * (Limited Release) The Marketplace Insights API provides the ability to search for sold items on eBay by keyword, 7 | * GTIN, category, and product and returns the of sales history of those items. 8 | */ 9 | export default class MarketplaceInsights extends Restful implements OpenApi { 10 | 11 | static id = 'MarketplaceInsights'; 12 | 13 | get basePath(): string { 14 | return '/buy/marketplace_insights/v1_beta'; 15 | } 16 | 17 | /** 18 | * (Limited Release) This method searches for sold eBay items by various URI query parameters and retrieves the sales 19 | * history of the items for the last 90 days. You can search by keyword, category, eBay product ID (ePID), or GTIN, 20 | * or a combination of these. 21 | * 22 | * @param itemId 23 | * @param aspectFilter This field lets you filter by item aspects. 24 | * @param categoryIds The category ID is required and is used to limit the results. 25 | * @param epid The ePID is the eBay product identifier of a product from the eBay product catalog. 26 | * @param fieldgroups This field lets you control what is to be returned in the response and accepts a comma separated list of values. 27 | * @param filter This field supports multiple field filters that can be used to limit/customize the result set. 28 | * @param gtin This field lets you search by the Global Trade Item Number of the item as defined by https://www.gtin.info. 29 | * @param limit The number of items, from the result set, returned in a single page. 30 | * @param offset Specifies the number of items to skip in the result set. 31 | * @param q A string consisting of one or more keywords that are used to search for items on eBay. 32 | * @param sort This field specifies the order and the field name to use to sort the items. 33 | */ 34 | public search({ 35 | aspectFilter, 36 | categoryIds, 37 | epid, 38 | fieldgroups, 39 | filter, 40 | gtin, 41 | limit, 42 | offset, 43 | q, 44 | sort, 45 | }: MarketingInsightsSearchParams) { 46 | return this.get(`/item_sales/search`, { 47 | params: { 48 | aspect_filter: aspectFilter, 49 | category_ids: categoryIds, 50 | epid, 51 | fieldgroups, 52 | filter, 53 | gtin, 54 | limit, 55 | offset, 56 | q, 57 | sort, 58 | } 59 | }); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /test/api/digitalSignature.spec.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai'; 2 | import 'mocha'; 3 | // @ts-ignore 4 | import sinon from 'sinon'; 5 | import {generateContentDigestValue, generateSignature, generateSignatureInput} from '../../src/api/digitalSignature.js'; 6 | 7 | const privateKey = ` 8 | -----BEGIN PRIVATE KEY----- 9 | MC4CAQAwBQYDK2VwBCIEIJ+DYvh6SEqVTm50DFtMDoQikTmiCqirVv9mWG9qfSnF 10 | -----END PRIVATE KEY-----`; 11 | 12 | describe('Digital Signature', () => { 13 | it('should be able to generate \'signature-input\' header when request has payload', () => { 14 | const signatureInput = generateSignatureInput({}, 123); 15 | expect(signatureInput).to.eql(`sig1=("content-digest" "x-ebay-signature-key" "@method" "@path" "@authority");created=123`); 16 | }); 17 | 18 | it('should be able to generate \'signature-input\' header when request has no payload', () => { 19 | const signatureInput = generateSignatureInput(null, 123); 20 | expect(signatureInput).to.eql(`sig1=("x-ebay-signature-key" "@method" "@path" "@authority");created=123`); 21 | }); 22 | 23 | it('should be able to generate \'Signature\' header', () => { 24 | const payload = '{"hello": "world"}'; 25 | const contentDigest = generateContentDigestValue(payload); 26 | expect(contentDigest).to.eql('sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:'); 27 | const signature = generateSignature({ 28 | 'content-digest': contentDigest, 29 | 'signature-input': 'sig1=("content-digest" "x-ebay-signature-key" "@method" "@path" "@authority");created=1663459378', 30 | 'x-ebay-signature-key': 'eyJhbGciOiJBMjU2R0NNS1ciLCJlbmMiOiJBMjU2R0NNIiwiemlwIjoiREVGIiwiaXYiOiJvSzFwdXJNVHQtci14VUwzIiwidGFnIjoiTjB4WjI4ZklZckFmYkd5UWFrTnpjZyJ9.AYdKU7ObIc7Z764OrlKpwUViK8Rphxl0xMP9v2_o9mI.1DbZiSQNRK6pLeIw.Yzp3IDV8RM_h_lMAnwGpMA4DXbaDdmqAh-65kO9xyDgzHD6s0kY3p-yO6oPR9kEcAbjGXIULeQKWVYzbfHKwXTY09Npj_mNuO5yxgZtWnL55uIgP2HL1So2dKkZRK0eyPa6DEXJT71lPtwZtpIGyq9R5h6s3kGMbqA.m4t_MX4VnlXJGx1X_zZ-KQ' 31 | }, privateKey, { 32 | method: 'POST', 33 | authority: 'localhost:8080', 34 | path: '/test' 35 | }, payload, 1663459378); 36 | expect(signature).to.eql('sig1=:gkk7dqudw21DFHDVBoRUWe/F6/2hTEmWRFDBxiN6COD4PjozXziiDFML1nFHu+0UcMXC/niltxzABjnugu4DCA==:'); 37 | }); 38 | 39 | it('should throw an error if content-digest is not in the header', () => { 40 | expect(() => generateSignature({}, privateKey, { 41 | method: 'POST', 42 | authority: 'localhost:8080', 43 | path: '/test' 44 | }, {}, 1663459378)).to.throw(/content-digest/); 45 | }); 46 | 47 | it('should throw an error pseudo header is not known', () => { 48 | expect(() => generateSignature({}, privateKey, { 49 | method: 'POST', 50 | authority: 'localhost:8080', 51 | path: '/test' 52 | }, {}, 1663459378)).to.throw(/content-digest/); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /src/api/restful/sell/logistics/index.ts: -------------------------------------------------------------------------------- 1 | import {operations} from '../../../../types/restful/specs/sell_logistics_v1_oas3.js'; 2 | import Restful, {OpenApi} from '../../index.js'; 3 | 4 | /** 5 | * The Logistics API resources offer the following capabilities:
  • shipping_quote – Consolidates into a list a set of live shipping rates, or quotes, from which you can select a rate to ship a package. 6 | */ 7 | export default class Logistics extends Restful implements OpenApi { 8 | 9 | static id = 'Logistics'; 10 | 11 | get basePath(): string { 12 | return '/sell/logistics/v1_beta'; 13 | } 14 | 15 | /** 16 | * The createShippingQuote method returns a shipping quote that contains a list of live "rates." 17 | * 18 | * @param data The ShippingQuoteRequest 19 | */ 20 | public createShippingQuote(data: any) { 21 | return this.post(`/shipping_quote`, data); 22 | } 23 | 24 | /** 25 | * This method retrieves the complete details of the shipping quote associated with the specified shippingQuoteId value. 26 | * 27 | * @param shippingQuoteId This path parameter specifies the unique eBay-assigned ID of the shipping quote you want to retrieve. 28 | */ 29 | public getShippingQuote(shippingQuoteId: string) { 30 | shippingQuoteId = encodeURIComponent(shippingQuoteId); 31 | return this.get(`/shipping_quote/${shippingQuoteId}`); 32 | } 33 | 34 | /** 35 | * This method creates a "shipment" based on the shippingQuoteId and rateId values supplied in the request. 36 | * 37 | * @param data The CreateShipmentFromQuoteRequest 38 | */ 39 | public createFromShippingQuote(data: any) { 40 | return this.post(`/shipment/create_from_shipping_quote`, data); 41 | } 42 | 43 | /** 44 | * This method retrieves the shipment details for the specified shipment ID. 45 | * 46 | * @param shipmentId This path parameter specifies the unique eBay-assigned ID of the shipment you want to retrieve. 47 | */ 48 | public getShipment(shipmentId: any) { 49 | return this.get(`/shipment/${shipmentId}`); 50 | } 51 | 52 | /** 53 | * This method returns the shipping label file that was generated for the shipmentId value specified in the request. 54 | * 55 | * @param shipmentId This path parameter specifies the unique eBay-assigned ID of the shipment associated with the shipping label you want to download. 56 | */ 57 | public downloadLabelFile(shipmentId: any) { 58 | return this.get(`/shipment/${shipmentId}/download_label_file`); 59 | } 60 | 61 | /** 62 | * This method cancels the shipment associated with the specified shipment ID and the associated shipping label is deleted. 63 | * 64 | * @param shipmentId This path parameter specifies the unique eBay-assigned ID of the shipment to be canceled. 65 | */ 66 | public cancelShipment(shipmentId: any) { 67 | return this.post(`/shipment/${shipmentId}/cancel`); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/api/restful/buy/feed/index.ts: -------------------------------------------------------------------------------- 1 | import {BuyFeedParams} from '../../../../types/index.js'; 2 | import {operations} from '../../../../types/restful/specs/buy_feed_v1_beta_oas3.js'; 3 | import Restful, {OpenApi} from '../../index.js'; 4 | 5 | /** 6 | * The Feed API provides the ability to download TSV_GZIP feed files containing eBay items and an hourly snapshot file 7 | * of the items that have changed within an hour for a specific category, date and marketplace. 8 | */ 9 | export default class Feed extends Restful implements OpenApi { 10 | 11 | static id = 'Feed'; 12 | 13 | get basePath() { 14 | return '/buy/feed/v1_beta'; 15 | } 16 | 17 | /** 18 | * This method lets you download a TSV_GZIP (tab separated value gzip) Item feed file. 19 | * 20 | * @param {BuyFeedParams} params 21 | * @param range his header specifies the range in bytes of the chunks of the gzip file being returned. 22 | * Format: bytes=startpos-endpos For example, the following retrieves the first 10 MBs of the feed file. 23 | */ 24 | public getItemFeed(params: BuyFeedParams, range: string) { 25 | return this.get(`/item`, { 26 | params, 27 | headers: { 28 | 'Range': range 29 | } 30 | }); 31 | } 32 | 33 | /** 34 | * This method lets you download a TSV_GZIP (tab separated value gzip) Item Group feed file. 35 | * @param {BuyFeedParams} params 36 | * @param range his header specifies the range in bytes of the chunks of the gzip file being returned. 37 | * Format: bytes=startpos-endpos For example, the following retrieves the first 10 MBs of the feed file. 38 | */ 39 | public getItemGroupFeed(params: BuyFeedParams, range: string) { 40 | return this.get(`/item_group`, { 41 | params, 42 | headers: { 43 | 'Range': range 44 | } 45 | }); 46 | } 47 | 48 | /** 49 | * The Hourly Snapshot feed file is generated each hour every day for all categories. 50 | * 51 | * @param {BuyFeedParams} params 52 | * @param {String} snapshotDate 53 | * @param range his header specifies the range in bytes of the chunks of the gzip file being returned. 54 | * Format: bytes=startpos-endpos For example, the following retrieves the first 10 MBs of the feed file. 55 | */ 56 | public getItemSnapshotFeed(params: BuyFeedParams, snapshotDate: string, range: string) { 57 | return this.get(`/item_snapshot`, { 58 | params: { 59 | ...params, 60 | snapshot_date: snapshotDate 61 | }, 62 | headers: { 63 | 'Range': range 64 | } 65 | }); 66 | } 67 | 68 | /** 69 | * The Hourly Snapshot feed file is generated each hour every day for all categories. 70 | * 71 | * @param {BuyFeedParams} params 72 | * @param {String} snapshotDate 73 | * @param range his header specifies the range in bytes of the chunks of the gzip file being returned. 74 | * Format: bytes=startpos-endpos For example, the following retrieves the first 10 MBs of the feed file. 75 | */ 76 | public getProductFeed(params: BuyFeedParams, snapshotDate: string, range: string) { 77 | return this.get(`/product`, { 78 | params: { 79 | ...params, 80 | snapshot_date: snapshotDate 81 | }, 82 | headers: { 83 | 'Range': range 84 | } 85 | }); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/types/traditional/get-best-offers-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetBestOffers.html#Output 2 | import type { 3 | AddressType, 4 | CurrencyCodeType, 5 | StandardOutputFields, 6 | } from './common.js'; 7 | 8 | export interface GetBestOffersResponse extends StandardOutputFields { 9 | BestOfferArray: { 10 | BestOffer: { 11 | BestOfferCodeType: 12 | | 'BuyerBestOffer' 13 | | 'BuyerCounterOffer' 14 | | 'CustomCode' 15 | | 'SellerCounterOffer'; 16 | BestOfferID: string; 17 | Buyer: { 18 | Email?: string; 19 | FeedbackScore: number; 20 | RegistrationDate: string; 21 | ShippingAddress?: AddressType; 22 | UserID?: string; 23 | }; 24 | BuyerMessage?: string; 25 | ExpirationTime: string; 26 | Price?: number | { value: number; currencyID: CurrencyCodeType }; 27 | Quantity: number; 28 | SellerMessage?: string; 29 | Status: 30 | | 'Accepted' 31 | | 'Active' 32 | | 'AdminEnded' 33 | | 'All' 34 | | 'Countered' 35 | | 'CustomCode' 36 | | 'Declined' 37 | | 'Expired' 38 | | 'Pending' 39 | | 'PendingBuyerConfirmation' 40 | | 'PendingBuyerPayment' 41 | | 'Retracted' 42 | | 'SellerAccept'; 43 | }; 44 | }; 45 | Item?: { 46 | BuyItNowPrice?: number | { value: number; currencyID: CurrencyCodeType }; 47 | Currency?: CurrencyCodeType; 48 | ItemID?: string; 49 | ListingDetails: { 50 | EndTime?: string; 51 | }; 52 | }; 53 | ItemBestOffersArray?: { 54 | ItemBestOffers?: { 55 | BestOfferArray?: { 56 | BestOffer: { 57 | BestOfferCodeType: 58 | | 'BuyerBestOffer' 59 | | 'BuyerCounterOffer' 60 | | 'CustomCode' 61 | | 'SellerCounterOffer'; 62 | BestOfferID: string; 63 | Buyer: { 64 | Email?: string; 65 | FeedbackScore: number; 66 | RegistrationDate: string; 67 | ShippingAddress?: AddressType; 68 | UserID?: string; 69 | }; 70 | BuyerMessage?: string; 71 | ExpirationTime: string; 72 | Price?: number | { value: number; currencyID: CurrencyCodeType }; 73 | Quantity: number; 74 | SellerMessage?: string; 75 | Status: 76 | | 'Accepted' 77 | | 'Active' 78 | | 'AdminEnded' 79 | | 'All' 80 | | 'Countered' 81 | | 'CustomCode' 82 | | 'Declined' 83 | | 'Expired' 84 | | 'Pending' 85 | | 'PendingBuyerConfirmation' 86 | | 'PendingBuyerPayment' 87 | | 'Retracted' 88 | | 'SellerAccept'; 89 | }; 90 | }; 91 | Item?: { 92 | BuyItNowPrice?: 93 | | number 94 | | { value: number; currencyID: CurrencyCodeType }; 95 | Currency?: CurrencyCodeType; 96 | ItemID?: string; 97 | ListingDetails: { 98 | EndTime?: string; 99 | }; 100 | }; 101 | Role?: 'Buyer' | 'CustomCode' | 'Seller'; 102 | }; 103 | }; 104 | PageNumber?: number; 105 | PaginationResult?: { 106 | TotalNumberOfEntries?: number; 107 | TotalNumberOfPages?: number; 108 | }; 109 | } 110 | -------------------------------------------------------------------------------- /src/api/restful/postOrder/cancellation/index.ts: -------------------------------------------------------------------------------- 1 | import Restful from '../../index.js'; 2 | import { 3 | CancellationSearchParams, 4 | ConfirmRefundRequest, 5 | CreateCancelRequest, 6 | RejectCancelRequest 7 | } from '../../../../types/index.js'; 8 | 9 | /** 10 | * Post-Order Cancellation API 11 | */ 12 | export default class Cancellation extends Restful { 13 | 14 | static id = 'Cancellation'; 15 | 16 | get basePath(): string { 17 | return '/post-order/v2'; 18 | } 19 | 20 | get useIaf() { 21 | return true; 22 | } 23 | 24 | /** 25 | * Seller approves a cancellation request 26 | * 27 | * @param cancelId The unique eBay-assigned identifier of the cancellation request to be approved. 28 | */ 29 | public approveCancellationRequest(cancelId: string) { 30 | cancelId = encodeURIComponent(cancelId); 31 | return this.post(`/cancellation/${cancelId}/approve`); 32 | } 33 | 34 | /** 35 | * Check the eligibility of an order cancellation 36 | * 37 | * @param legacyOrderId The unique ID of the order being canceled or the order being considered for cancellation. 38 | */ 39 | public checkCancellationEligibility(legacyOrderId: string) { 40 | return this.post(`/cancellation/check_eligibility`, { 41 | legacyOrderId 42 | }); 43 | } 44 | 45 | /** 46 | * Buyer confirms the refund from a cancellation was received 47 | * 48 | * @param cancelId The unique eBay-assigned identifier of the cancellation/refund being confirmed. 49 | * @param payload the ConfirmRefundReceivedPayload 50 | */ 51 | public confirmRefundReceived(cancelId: string, payload?: ConfirmRefundRequest) { 52 | cancelId = encodeURIComponent(cancelId); 53 | return this.post(`/cancellation/${cancelId}/confirm`, payload); 54 | } 55 | 56 | /** 57 | * Request or perform an order cancellation. 58 | * 59 | * @param payload the CreateCancelRequest 60 | */ 61 | public createCancellation(payload: CreateCancelRequest) { 62 | return this.post(`/cancellation`, payload); 63 | } 64 | 65 | /** 66 | * Retrieve the details of an order cancellation. 67 | * 68 | * @param cancelId Supply in this path parameter the unique eBay-assigned ID of the cancellation request to 69 | * retrieve. 70 | * @param fieldGroups The value set in this query parameter controls the level of detail that is returned in the 71 | * response. 72 | */ 73 | public getCancellation(cancelId: string, fieldGroups?: string) { 74 | cancelId = encodeURIComponent(cancelId); 75 | return this.get(`/cancellation/${cancelId}`, { 76 | params: { 77 | fieldgroups: fieldGroups 78 | } 79 | }); 80 | } 81 | 82 | /** 83 | * Seller rejects a cancellation request. 84 | * 85 | * @param cancelId The unique eBay-assigned identifier of the cancellation request to be rejected. 86 | * @param payload the RejectCancelRequest 87 | */ 88 | public rejectCancellationRequest(cancelId: string, payload?: RejectCancelRequest) { 89 | cancelId = encodeURIComponent(cancelId); 90 | return this.post(`/cancellation/${cancelId}/reject`, payload); 91 | } 92 | 93 | /** 94 | * Search for cancellations. 95 | * 96 | * @param params the SearchParams 97 | */ 98 | public search(params: CancellationSearchParams) { 99 | return this.get(`/cancellation/search`, { 100 | params 101 | }); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/types/traditional/get-shipping-discount-profiles-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetShippingDiscountProfiles.html#Output 2 | import type { CurrencyCodeType, StandardOutputFields } from './common.js'; 3 | 4 | export interface GetShippingDiscountProfilesResponse 5 | extends StandardOutputFields { 6 | CalculatedHandlingDiscount: { 7 | DiscountName?: 8 | | 'CombinedHandlingFee' 9 | | 'CustomCode' 10 | | 'EachAdditionalAmount' 11 | | 'EachAdditionalAmountOff' 12 | | 'EachAdditionalPercentOff' 13 | | 'IndividualHandlingFee'; 14 | EachAdditionalAmount?: 15 | | number 16 | | { value: number; currencyID: CurrencyCodeType }; 17 | EachAdditionalOffAmount?: 18 | | number 19 | | { value: number; currencyID: CurrencyCodeType }; 20 | EachAdditionalPercentOff?: number; 21 | OrderHandlingAmount?: 22 | | number 23 | | { value: number; currencyID: CurrencyCodeType }; 24 | }; 25 | CalculatedShippingDiscount: { 26 | DiscountName?: 27 | | 'CombinedItemWeight' 28 | | 'CustomCode' 29 | | 'EachAdditionalAmount' 30 | | 'EachAdditionalAmountOff' 31 | | 'EachAdditionalPercentOff' 32 | | 'IndividualItemWeight' 33 | | 'MaximumShippingCostPerOrder' 34 | | 'ShippingCostXForAmountY' 35 | | 'ShippingCostXForItemCountN' 36 | | 'WeightOff'; 37 | DiscountProfile?: { 38 | DiscountProfileID: string; 39 | DiscountProfileName?: string; 40 | MappedDiscountProfileID?: string; 41 | WeightOff?: 42 | | number 43 | | { 44 | value: number; 45 | unit: string; 46 | measurementSystem: 'English' | 'Metric'; 47 | }; 48 | }; 49 | }; 50 | CombinedDuration: 51 | | 'CustomCode' 52 | | 'Days_14' 53 | | 'Days_3' 54 | | 'Days_30' 55 | | 'Days_5' 56 | | 'Days_7' 57 | | 'Ineligible'; 58 | CurrencyID: CurrencyCodeType; 59 | FlatShippingDiscount: { 60 | DiscountName?: 61 | | 'CombinedItemWeight' 62 | | 'CustomCode' 63 | | 'EachAdditionalAmount' 64 | | 'EachAdditionalAmountOff' 65 | | 'EachAdditionalPercentOff' 66 | | 'IndividualItemWeight' 67 | | 'MaximumShippingCostPerOrder' 68 | | 'ShippingCostXForAmountY' 69 | | 'ShippingCostXForItemCountN' 70 | | 'WeightOff'; 71 | DiscountProfile?: { 72 | DiscountProfileID: string; 73 | DiscountProfileName?: string; 74 | EachAdditionalAmount?: 75 | | number 76 | | { value: number; currencyID: CurrencyCodeType }; 77 | EachAdditionalAmountOff?: 78 | | number 79 | | { value: number; currencyID: CurrencyCodeType }; 80 | EachAdditionalPercentOff?: number; 81 | }; 82 | }; 83 | PromotionalShippingDiscount: boolean; 84 | PromotionalShippingDiscountDetails?: { 85 | DiscountName?: 86 | | 'CombinedItemWeight' 87 | | 'CustomCode' 88 | | 'EachAdditionalAmount' 89 | | 'EachAdditionalAmountOff' 90 | | 'EachAdditionalPercentOff' 91 | | 'IndividualItemWeight' 92 | | 'MaximumShippingCostPerOrder' 93 | | 'ShippingCostXForAmountY' 94 | | 'ShippingCostXForItemCountN' 95 | | 'WeightOff'; 96 | ItemCount?: number; 97 | OrderAmount?: number | { value: number; currencyID: CurrencyCodeType }; 98 | ShippingCost?: number | { value: number; currencyID: CurrencyCodeType }; 99 | }; 100 | } 101 | -------------------------------------------------------------------------------- /src/api/restful/postOrder/case/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AppealRequest, 3 | BuyerCloseCaseRequest, 4 | CaseSearchParams, 5 | ReturnAddressRequest, 6 | Text 7 | } from '../../../../types/index.js'; 8 | import Restful from '../../index.js'; 9 | 10 | /** 11 | * Post-Order Case Management API 12 | */ 13 | export default class Case extends Restful { 14 | 15 | static id = 'Case'; 16 | 17 | get basePath(): string { 18 | return '/post-order/v2'; 19 | } 20 | 21 | get useIaf() { 22 | return true; 23 | } 24 | 25 | /** 26 | * Buyer or seller appeals a case decision. 27 | * 28 | * @param caseId The unique identifier of a case. 29 | * @param payload the AppealRequest 30 | */ 31 | public appealCaseDecision(caseId: string, payload?: AppealRequest) { 32 | const id = encodeURIComponent(caseId); 33 | return this.post(`/casemanagement/${id}/appeal`, payload); 34 | } 35 | 36 | /** 37 | * Check the eligibility of an order cancellation. 38 | * 39 | * @param caseId The unique identifier of a case. 40 | * @param payload the BuyerCloseCaseRequest 41 | */ 42 | public closeCase(caseId: string, payload: BuyerCloseCaseRequest) { 43 | const id = encodeURIComponent(caseId); 44 | return this.post(`/casemanagement/${id}/close`, payload); 45 | } 46 | 47 | /** 48 | * Retrieve the details related to a specific case. 49 | * 50 | * @param caseId The unique identifier of a case. 51 | */ 52 | public getCase(caseId: string) { 53 | const id = encodeURIComponent(caseId); 54 | return this.get(`/casemanagement/${id}`); 55 | } 56 | 57 | /** 58 | * Seller issues a refund for a case. 59 | * 60 | * @param caseId The unique identifier of a case. 61 | * @param payload the CaseVoluntaryRefundRequest (Text) 62 | */ 63 | public issueCaseRefund(caseId: string, payload?: Text) { 64 | const id = encodeURIComponent(caseId); 65 | return this.post(`/casemanagement/${id}/issue_refund`, payload); 66 | } 67 | 68 | /** 69 | * This call allows the buyer to provide shipment tracking information for the item that is being returned to the 70 | * seller. 71 | * 72 | * @param caseId The unique identifier of a case. 73 | * @param shippingCarrierName The shipping carrier that is used to ship the item, such as 'FedEx', 'UPS', or 74 | * 'USPS'. 75 | * @param trackingNumber The tracking number assigned by the shipping carrier to the item shipment. 76 | */ 77 | public provideReturnShipmentInfo(caseId: string, {shippingCarrierName, trackingNumber}: 78 | { shippingCarrierName: string, trackingNumber: string }) { 79 | const id = encodeURIComponent(caseId); 80 | return this.post(`/casemanagement/${id}/provide_shipment_info`, { 81 | shippingCarrierName, 82 | trackingNumber 83 | }); 84 | } 85 | 86 | /** 87 | * Seller provides a return address to the buyer. 88 | * 89 | * @param cancelId The unique eBay-assigned identifier of the cancellation request to be rejected. 90 | * @param payload the ReturnAddressRequest 91 | */ 92 | public providesReturnAddress(cancelId: string, payload?: ReturnAddressRequest) { 93 | const id = encodeURIComponent(cancelId); 94 | return this.post(`/casemanagement/${id}/provide_return_address`, payload); 95 | } 96 | 97 | /** 98 | * This call is used to search for cases using multiple filter types. 99 | * 100 | * @param params the SearchParams 101 | */ 102 | public search(params: CaseSearchParams) { 103 | return this.get(`/casemanagement/search`, { 104 | params 105 | }); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/types/traditional/index.ts: -------------------------------------------------------------------------------- 1 | // Export common types 2 | export * from './common.js'; 3 | 4 | // Export all Trading API response types 5 | export * from './add-fixed-price-item-response.js'; 6 | export * from './add-item-response.js'; 7 | export * from './add-items-response.js'; 8 | export * from './add-member-message-a-a-q-to-partner-response.js'; 9 | export * from './add-member-message-r-t-q-response.js'; 10 | export * from './add-member-messages-a-a-q-to-bidder-response.js'; 11 | export * from './add-order-response.js'; 12 | export * from './add-second-chance-item-response.js'; 13 | export * from './add-to-item-description-response.js'; 14 | export * from './add-to-watch-list-response.js'; 15 | export * from './complete-sale-response.js'; 16 | export * from './delete-my-messages-response.js'; 17 | export * from './end-fixed-price-item-response.js'; 18 | export * from './end-items-response.js'; 19 | export * from './fetch-token-response.js'; 20 | export * from './get-account-response.js'; 21 | export * from './get-ad-format-leads-response.js'; 22 | export * from './get-all-bidders-response.js'; 23 | export * from './get-best-offers-response.js'; 24 | export * from './get-bidder-list-response.js'; 25 | export * from './get-categories-response.js'; 26 | export * from './get-category-features-response.js'; 27 | export * from './get-description-templates-response.js'; 28 | export * from './get-feedback-response.js'; 29 | export * from './get-item-response.js'; 30 | export * from './get-items-awaiting-feedback-response.js'; 31 | export * from './get-member-messages-response.js'; 32 | export * from './get-message-preferences-response.js'; 33 | export * from './get-my-messages-response.js'; 34 | export * from './get-seller-list-response.js'; 35 | export * from './get-seller-transactions-response.js'; 36 | export * from './get-shipping-discount-profiles-response.js'; 37 | export * from './get-store-response.js'; 38 | export * from './get-tax-table-response.js'; 39 | export * from './get-token-status-response.js'; 40 | export * from './get-user-contact-details-response.js'; 41 | export * from './get-user-preferences-response.js'; 42 | export * from './get-user-response.js'; 43 | export * from './get-ve-r-o-reason-code-details-response.js'; 44 | export * from './get-ve-r-o-report-status-response.js'; 45 | export * from './gete-bay-details-response.js'; 46 | export * from './place-offer-response.js'; 47 | export * from './relist-fixed-price-item-response.js'; 48 | export * from './relist-item-response.js'; 49 | export * from './remove-from-watch-list-response.js'; 50 | export * from './respond-to-best-offer-response.js'; 51 | export * from './respond-to-feedback-response.js'; 52 | export * from './revise-fixed-price-item-response.js'; 53 | export * from './revise-inventory-status-response.js'; 54 | export * from './revise-item-response.js'; 55 | export * from './revise-my-messages-folders-response.js'; 56 | export * from './revise-my-messages-response.js'; 57 | export * from './revoke-token-response.js'; 58 | export * from './send-invoice-response.js'; 59 | export * from './set-message-preferences-response.js'; 60 | export * from './set-notification-preferences-response.js'; 61 | export * from './set-shipping-discount-profiles-response.js'; 62 | export * from './set-store-categories-response.js'; 63 | export * from './set-tax-table-response.js'; 64 | export * from './set-user-notes-response.js'; 65 | export * from './set-user-preferences-response.js'; 66 | export * from './upload-site-hosted-pictures-response.js'; 67 | export * from './ve-r-o-report-items-response.js'; 68 | export * from './verify-add-fixed-price-item-response.js'; 69 | export * from './verify-add-item-response.js'; 70 | export * from './verify-add-second-chance-item-response.js'; 71 | export * from './verify-relist-item-response.js'; 72 | -------------------------------------------------------------------------------- /src/api/restful/buy/deal/index.ts: -------------------------------------------------------------------------------- 1 | import {operations} from '../../../../types/restful/specs/buy_deal_v1_oas3.js'; 2 | import Restful, {OpenApi} from '../../index.js'; 3 | 4 | /** 5 | * This API allows third-party developers to search for and retrieve details about eBay deals and events, as well as the items associated with those deals and events. 6 | */ 7 | export default class Deal extends Restful implements OpenApi { 8 | 9 | static id = 'Deal'; 10 | 11 | get basePath(): string { 12 | return '/buy/deal/v1'; 13 | } 14 | 15 | /** 16 | * This method retrieves a paginated set of deal items. 17 | * 18 | * @param categoryIds The unique identifier of the eBay category for the search. 19 | * @param commissionable A filter for commissionable deals. Restriction: This filter is currently only supported for the US marketplace. 20 | * @param deliveryCountry A filter for items that can be shipped to the specified country. 21 | * @param limit The maximum number of items, from the current result set, returned on a single page. 22 | * @param offset The number of items that will be skipped in the result set. 23 | */ 24 | public getDealItems({ 25 | categoryIds, 26 | commissionable, 27 | deliveryCountry, 28 | limit, 29 | offset 30 | }: { 31 | categoryIds?: string, 32 | commissionable?: string, 33 | deliveryCountry?: string, 34 | limit?: string, 35 | offset?: string 36 | }) { 37 | return this.get(`/deal_item`, { 38 | params: { 39 | category_ids: categoryIds, 40 | commissionable, 41 | delivery_country: deliveryCountry, 42 | limit, 43 | offset 44 | } 45 | }); 46 | } 47 | 48 | /** 49 | * This method retrieves the details for an eBay event. 50 | * 51 | * @param eventId The unique identifier for the eBay event. 52 | */ 53 | public getEvent(eventId: string) { 54 | eventId = encodeURIComponent(eventId); 55 | return this.get(`/event/${eventId}`); 56 | } 57 | 58 | /** 59 | * This method returns paginated results containing all eBay events for the specified marketplace. 60 | * 61 | * @param limit The maximum number of items, from the current result set, returned on a single page. Default: 20 Maximum Value: 100 62 | * @param offset The number of items that will be skipped in the result set. 63 | */ 64 | public getEvents({limit, offset}: { limit?: string, offset?: string, }) { 65 | return this.get(`/event`, { 66 | params: { 67 | limit, 68 | offset 69 | } 70 | }); 71 | } 72 | 73 | /** 74 | * This method returns paginated results containing all eBay events for the specified marketplace. 75 | * 76 | * @param eventIds The unique identifiers for the eBay events. Maximum Value: 1 77 | * @param categoryIds The unique identifier of the eBay category for the search. Maximum Value: 1 78 | * @param deliveryCountry A filter for items that can be shipped to the specified country. 79 | * @param limit The maximum number of items, from the current result set, returned on a single page. Default: 20 Maximum Value: 100 80 | * @param offset The number of items that will be skipped in the result set. 81 | */ 82 | public getEventItems(eventIds: string, { 83 | categoryIds, 84 | deliveryCountry, 85 | limit, 86 | offset 87 | }: { categoryIds?: string, deliveryCountry?: string, limit?: string, offset?: string, } = {}) { 88 | return this.get(`/event_item`, { 89 | params: { 90 | event_ids: eventIds, 91 | limit, 92 | offset, 93 | category_ids: categoryIds, 94 | delivery_country: deliveryCountry 95 | } 96 | }); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/types/restful/specs/cancellation_oas3.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file was auto-generated by openapi-typescript. 3 | * Do not make direct changes to the file. 4 | */ 5 | 6 | 7 | export interface paths { 8 | "/cancellation/{cancelId}/approve": { 9 | /** @description Seller approves a cancellation request */ 10 | post: operations["approveCancellationRequest"]; 11 | }; 12 | "/cancellation/check_eligibility": { 13 | /** @description Check the eligibility of an order cancellation */ 14 | post: operations["checkCancellationEligibility"]; 15 | }; 16 | "/cancellation/{cancelId}/confirm": { 17 | /** @description Buyer confirms the refund from a cancellation was received */ 18 | post: operations["confirmRefundReceived"]; 19 | }; 20 | "/cancellation": { 21 | /** @description Request or perform an order cancellation */ 22 | post: operations["createCancellation"]; 23 | }; 24 | "/cancellation/{cancelId}": { 25 | /** @description Request or perform an order cancellation */ 26 | get: operations["getCancellation"]; 27 | }; 28 | "/cancellation/{cancelId}/reject": { 29 | /** @description Seller rejects a cancellation request */ 30 | post: operations["rejectCancellationRequest"]; 31 | }; 32 | "/cancellation/search": { 33 | /** @description Search for cancellations */ 34 | get: operations["search"]; 35 | }; 36 | } 37 | 38 | export type webhooks = Record; 39 | 40 | export type components = Record; 41 | 42 | export type external = Record; 43 | 44 | export interface operations { 45 | 46 | /** @description Seller approves a cancellation request */ 47 | approveCancellationRequest: { 48 | parameters: { 49 | path: { 50 | /** @description The unique eBay-assigned identifier of the cancellation request to be approved. */ 51 | cancelId: string; 52 | }; 53 | }; 54 | responses: { 55 | /** @description OK */ 56 | 200: never; 57 | }; 58 | }; 59 | /** @description Check the eligibility of an order cancellation */ 60 | checkCancellationEligibility: { 61 | responses: { 62 | /** @description OK */ 63 | 200: never; 64 | }; 65 | }; 66 | /** @description Buyer confirms the refund from a cancellation was received */ 67 | confirmRefundReceived: { 68 | parameters: { 69 | path: { 70 | /** @description The unique eBay-assigned identifier of the cancellation request to be approved. */ 71 | cancelId: string; 72 | }; 73 | }; 74 | responses: { 75 | /** @description OK */ 76 | 200: never; 77 | }; 78 | }; 79 | /** @description Request or perform an order cancellation */ 80 | createCancellation: { 81 | responses: { 82 | /** @description OK */ 83 | 200: never; 84 | }; 85 | }; 86 | /** @description Request or perform an order cancellation */ 87 | getCancellation: { 88 | parameters: { 89 | path: { 90 | /** @description The unique eBay-assigned identifier of the cancellation request to be approved. */ 91 | cancelId: string; 92 | }; 93 | }; 94 | responses: { 95 | /** @description OK */ 96 | 200: never; 97 | }; 98 | }; 99 | /** @description Seller rejects a cancellation request */ 100 | rejectCancellationRequest: { 101 | parameters: { 102 | path: { 103 | /** @description The unique eBay-assigned identifier of the cancellation request to be approved. */ 104 | cancelId: string; 105 | }; 106 | }; 107 | responses: { 108 | /** @description OK */ 109 | 200: never; 110 | }; 111 | }; 112 | /** @description Search for cancellations */ 113 | search: { 114 | responses: { 115 | /** @description OK */ 116 | 200: never; 117 | }; 118 | }; 119 | } 120 | -------------------------------------------------------------------------------- /src/types/traditional/get-user-preferences-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetUserPreferences.html#Output 2 | import type { 3 | CountryCodeType, 4 | CurrencyCodeType, 5 | StandardOutputFields, 6 | } from './common.js'; 7 | 8 | export interface GetUserPreferencesResponse extends StandardOutputFields { 9 | BidderNoticePreferences: { 10 | UnsuccessfulBidderNoticeIncludeMyItems?: boolean; 11 | }; 12 | CombinedPaymentPreferences?: { 13 | CombinedPaymentOption?: 14 | | 'CustomCode' 15 | | 'DiscountSpecified' 16 | | 'NoCombinedPayment' 17 | | 'SpecifyDiscountLater'; 18 | }; 19 | DispatchCutoffTimePreference?: { 20 | CutoffTime?: string; 21 | }; 22 | EmailShipmentTrackingNumberPreference?: boolean; 23 | EndOfAuctionEmailPreferences?: { 24 | EmailCustomized: boolean; 25 | LogoCustomized?: boolean; 26 | LogoType: 27 | | 'CustomCode' 28 | | 'Customized' 29 | | 'None' 30 | | 'Store' 31 | | 'WinningBidderNotice'; 32 | LogoURL?: string; 33 | TemplateText?: string; 34 | TextCustomized?: boolean; 35 | }; 36 | GlobalShippingProgramListingPreference?: boolean; 37 | OfferGlobalShippingProgramPreference?: boolean; 38 | OutOfStockControlPreference?: boolean; 39 | OverrideGSPServiceWithIntlServicePreference?: boolean; 40 | PickupDropoffSellerPreference?: boolean; 41 | PurchaseReminderEmailPreferences?: { 42 | PurchaseReminderEmailPreferences?: boolean; 43 | }; 44 | RequiredShipPhoneNumberPreference?: boolean; 45 | SellerExcludeShipToLocationPreferences?: { 46 | ExcludeShipToLocation?: string; 47 | }; 48 | SellerFavoriteItemPreferences?: { 49 | FavoriteItemID?: string; 50 | ListingType?: 51 | | 'AdType' 52 | | 'Auction' 53 | | 'Chinese' 54 | | 'CustomCode' 55 | | 'FixedPriceItem' 56 | | 'LeadGeneration' 57 | | 'PersonalOffer' 58 | | 'Unknown'; 59 | MaxPrice?: number | { value: number; currencyID: CurrencyCodeType }; 60 | MinPrice?: number | { value: number; currencyID: CurrencyCodeType }; 61 | SearchKeywords?: string; 62 | SearchSortOrder?: 63 | | 'CustomCode' 64 | | 'EndingFirst' 65 | | 'HighestPriced' 66 | | 'HighestPricedPlusShipping' 67 | | 'LowestPriced' 68 | | 'LowestPricedPlusShipping' 69 | | 'NewlyListed'; 70 | StoreCategoryID?: bigint; 71 | }; 72 | SellerPaymentPreferences?: { 73 | AlwaysUseThisPaymentAddress?: boolean; 74 | DefaultPayPalEmailAddress?: string; 75 | DisplayPayNowButton?: string; 76 | FedExRateOption?: 77 | | 'CustomCode' 78 | | 'FedExCounter' 79 | | 'FedExDiscounted' 80 | | 'FedExStandardList'; 81 | PayPalAlwaysOn?: boolean; 82 | PayPalPreferred?: boolean; 83 | SellerPaymentAddress?: { 84 | Country?: CountryCodeType; 85 | }; 86 | UPSRateOption?: 'CustomCode' | 'UPSDailyRates' | 'UPSOnDemandRates'; 87 | USPSRateOption?: 'CustomCode' | 'USPSDiscounted' | 'USPSRetail'; 88 | }; 89 | SellerProfilePreferences?: { 90 | SellerProfileOptedIn?: boolean; 91 | SupportedSellerProfiles?: { 92 | SupportedSellerProfile?: { 93 | CategoryGroup?: { 94 | IsDefault?: boolean; 95 | Name?: string; 96 | }; 97 | ProfileID?: bigint; 98 | ProfileName?: string; 99 | ProfileType?: string; 100 | ShortSummary?: string; 101 | }; 102 | }; 103 | }; 104 | SellerReturnPreferences?: { 105 | OptedIn?: boolean; 106 | }; 107 | UnpaidItemAssistancePreferences?: { 108 | AutoRelist?: boolean; 109 | DelayBeforeOpeningDispute?: number; 110 | ExcludedUser?: string; 111 | OptInStatus?: boolean; 112 | RemoveAllExcludedUsers?: boolean; 113 | }; 114 | eBayPLUSPreference?: { 115 | Country?: CountryCodeType; 116 | ListingPreference?: boolean; 117 | OptInStatus?: boolean; 118 | }; 119 | } 120 | -------------------------------------------------------------------------------- /src/api/traditional/trading/index.ts: -------------------------------------------------------------------------------- 1 | enum calls { 2 | AddDispute, 3 | AddDisputeResponse, 4 | AddFixedPriceItem, 5 | AddItem, 6 | AddItemFromSellingManagerTemplate, 7 | AddItems, 8 | AddMemberMessageAAQToPartner, 9 | AddMemberMessageRTQ, 10 | AddMemberMessagesAAQToBidder, 11 | AddOrder, 12 | AddSecondChanceItem, 13 | AddSellingManagerInventoryFolder, 14 | AddSellingManagerProduct, 15 | AddSellingManagerTemplate, 16 | AddToItemDescription, 17 | AddToWatchList, 18 | AddTransactionConfirmationItem, 19 | CompleteSale, 20 | ConfirmIdentity, 21 | DeleteMyMessages, 22 | DeleteSellingManagerInventoryFolder, 23 | DeleteSellingManagerItemAutomationRule, 24 | DeleteSellingManagerProduct, 25 | DeleteSellingManagerTemplate, 26 | DeleteSellingManagerTemplateAutomationRule, 27 | DisableUnpaidItemAssistance, 28 | EndFixedPriceItem, 29 | EndItem, 30 | EndItems, 31 | ExtendSiteHostedPictures, 32 | FetchToken, 33 | GetAccount, 34 | GetAdFormatLeads, 35 | GetAllBidders, 36 | GetApiAccessRules, 37 | GetBestOffers, 38 | GetBidderList, 39 | GetCategories, 40 | GetCategoryFeatures, 41 | GetCategoryMappings, 42 | GetCategorySpecifics, 43 | GetChallengeToken, 44 | GetCharities, 45 | GetClientAlertsAuthToken, 46 | GetContextualKeywords, 47 | GetDescriptionTemplates, 48 | GetDispute, 49 | GeteBayDetails, 50 | GeteBayOfficialTime, 51 | GetFeedback, 52 | GetItem, 53 | GetItemsAwaitingFeedback, 54 | GetItemShipping, 55 | GetItemTransactions, 56 | GetMemberMessages, 57 | GetMessagePreferences, 58 | GetMyeBayBuying, 59 | GetMyeBayReminders, 60 | GetMyeBaySelling, 61 | GetMyMessages, 62 | GetNotificationPreferences, 63 | GetNotificationsUsage, 64 | GetOrders, 65 | GetOrderTransactions, 66 | GetPromotionalSaleDetails, 67 | GetSellerDashboard, 68 | GetSellerEvents, 69 | GetSellerList, 70 | GetSellerTransactions, 71 | GetSellingManagerAlerts, 72 | GetSellingManagerEmailLog, 73 | GetSellingManagerInventory, 74 | GetSellingManagerInventoryFolder, 75 | GetSellingManagerItemAutomationRule, 76 | GetSellingManagerSaleRecord, 77 | GetSellingManagerSoldListings, 78 | GetSellingManagerTemplateAutomationRule, 79 | GetSellingManagerTemplates, 80 | GetSessionID, 81 | GetShippingDiscountProfiles, 82 | GetStore, 83 | GetStoreCategoryUpdateStatus, 84 | GetStoreCustomPage, 85 | GetStoreOptions, 86 | GetStorePreferences, 87 | GetSuggestedCategories, 88 | GetTaxTable, 89 | GetTokenStatus, 90 | GetUser, 91 | GetUserContactDetails, 92 | GetUserDisputes, 93 | GetUserPreferences, 94 | GetVeROReasonCodeDetails, 95 | GetVeROReportStatus, 96 | LeaveFeedback, 97 | MoveSellingManagerInventoryFolder, 98 | PlaceOffer, 99 | RelistFixedPriceItem, 100 | RelistItem, 101 | RemoveFromWatchList, 102 | RespondToBestOffer, 103 | RespondToFeedback, 104 | ReviseCheckoutStatus, 105 | ReviseFixedPriceItem, 106 | ReviseInventoryStatus, 107 | ReviseItem, 108 | ReviseMyMessages, 109 | ReviseMyMessagesFolders, 110 | ReviseSellingManagerInventoryFolder, 111 | ReviseSellingManagerProduct, 112 | ReviseSellingManagerSaleRecord, 113 | ReviseSellingManagerTemplate, 114 | RevokeToken, 115 | SaveItemToSellingManagerTemplate, 116 | SellerReverseDispute, 117 | SendInvoice, 118 | SetMessagePreferences, 119 | SetNotificationPreferences, 120 | SetPromotionalSale, 121 | SetPromotionalSaleListings, 122 | SetSellingManagerFeedbackOptions, 123 | SetSellingManagerItemAutomationRule, 124 | SetSellingManagerTemplateAutomationRule, 125 | SetShippingDiscountProfiles, 126 | SetStore, 127 | SetStoreCategories, 128 | SetStoreCustomPage, 129 | SetStorePreferences, 130 | SetTaxTable, 131 | SetUserNotes, 132 | SetUserPreferences, 133 | UploadSiteHostedPictures, 134 | ValidateChallengeInput, 135 | ValidateTestUserRegistration, 136 | VerifyAddFixedPriceItem, 137 | VerifyAddItem, 138 | VerifyAddSecondChanceItem, 139 | VerifyRelistItem, 140 | VeROReportItems 141 | } 142 | 143 | export default calls; 144 | -------------------------------------------------------------------------------- /src/types/traditional/get-feedback-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetFeedback.html#Output 2 | import type { CurrencyCodeType, StandardOutputFields } from './common.js'; 3 | 4 | export interface GetFeedbackResponse extends StandardOutputFields { 5 | FeedbackDetailArray?: { 6 | FeedbackDetail?: { 7 | CommentReplaced?: boolean; 8 | CommentText?: string; 9 | CommentTime?: string; 10 | CommentType?: 11 | | 'CustomCode' 12 | | 'IndependentlyWithdrawn' 13 | | 'Negative' 14 | | 'Neutral' 15 | | 'Positive' 16 | | 'Withdrawn'; 17 | CommentingUser?: string; 18 | CommentingUserScore?: number; 19 | Countable?: boolean; 20 | FeedbackID?: string; 21 | FeedbackRatingStar?: 22 | | 'Blue' 23 | | 'CustomCode' 24 | | 'Green' 25 | | 'GreenShooting' 26 | | 'None' 27 | | 'Purple' 28 | | 'PurpleShooting' 29 | | 'Red' 30 | | 'RedShooting' 31 | | 'SilverShooting' 32 | | 'Turquoise' 33 | | 'TurquoiseShooting' 34 | | 'Yellow' 35 | | 'YellowShooting'; 36 | FeedbackResponse?: string; 37 | FeedbackRevised?: boolean; 38 | FollowUpReplaced?: boolean; 39 | Followup?: string; 40 | ItemID?: string; 41 | ItemPrice?: number | { value: number; currencyID: CurrencyCodeType }; 42 | ItemTitle?: string; 43 | OrderLineItemID?: string; 44 | ResponseReplaced?: boolean; 45 | Role?: 'Buyer' | 'CustomCode' | 'Seller'; 46 | TransactionID?: string; 47 | }; 48 | }; 49 | FeedbackDetailItemTotal?: number; 50 | FeedbackScore: number; 51 | FeedbackSummary?: { 52 | BidRetractionFeedbackPeriodArray?: { 53 | FeedbackPeriod?: { 54 | Count?: number; 55 | PeriodInDays?: number; 56 | }; 57 | }; 58 | BuyerRoleMetrics?: { 59 | FeedbackLeftPercent?: number; 60 | NegativeFeedbackLeftCount?: number; 61 | NeutralFeedbackLeftCount?: number; 62 | PositiveFeedbackLeftCount?: number; 63 | }; 64 | NegativeFeedbackPeriodArray?: { 65 | FeedbackPeriod?: { 66 | Count?: number; 67 | PeriodInDays?: number; 68 | }; 69 | }; 70 | NeutralCommentCountFromSuspendedUsers?: number; 71 | NeutralFeedbackPeriodArray?: { 72 | FeedbackPeriod?: { 73 | Count?: number; 74 | PeriodInDays?: number; 75 | }; 76 | }; 77 | PositiveFeedbackPeriodArray?: { 78 | FeedbackPeriod?: { 79 | Count?: number; 80 | PeriodInDays?: number; 81 | }; 82 | }; 83 | SellerRatingSummaryArray?: { 84 | AverageRatingSummary?: { 85 | AverageRatingDetails?: { 86 | Rating?: number; 87 | RatingCount?: number; 88 | RatingDetail?: 89 | | 'Communication' 90 | | 'CustomCode' 91 | | 'ItemAsDescribed' 92 | | 'ShippingAndHandlingCharges' 93 | | 'ShippingTime'; 94 | }; 95 | FeedbackSummaryPeriod?: 'CustomCode' | 'FiftyTwoWeeks' | 'ThirtyDays'; 96 | }; 97 | }; 98 | SellerRoleMetrics?: { 99 | CrossBorderTransactionCount?: number; 100 | CrossBorderTransactionPercent?: number; 101 | FeedbackLeftPercent?: number; 102 | NegativeFeedbackLeftCount?: number; 103 | NeutralFeedbackLeftCount?: number; 104 | PositiveFeedbackLeftCount?: number; 105 | RepeatBuyerCount?: number; 106 | RepeatBuyerPercent?: number; 107 | TransactionPercent?: number; 108 | UniqueBuyerCount?: number; 109 | }; 110 | TotalFeedbackPeriodArray?: { 111 | FeedbackPeriod?: { 112 | Count?: number; 113 | PeriodInDays?: number; 114 | }; 115 | }; 116 | UniqueNegativeFeedbackCount?: number; 117 | UniqueNeutralFeedbackCount?: number; 118 | UniquePositiveFeedbackCount?: number; 119 | }; 120 | PageNumber: number; 121 | PaginationResult: { 122 | TotalNumberOfEntries: number; 123 | TotalNumberOfPages: number; 124 | }; 125 | } 126 | -------------------------------------------------------------------------------- /specs/cancellation_oas3.json: -------------------------------------------------------------------------------- 1 | { 2 | "openapi": "3.0.0", 3 | "info": { 4 | "version": "0.1", 5 | "title": "Post Order Cancellation API", 6 | "description": "Custom Cancellation API OAS definition." 7 | }, 8 | "servers": [ 9 | { 10 | "url": "https://api.ebay.com{basePath}", 11 | "description": "Cancellation", 12 | "variables": { 13 | "basePath": { 14 | "default": "/post-order/v2" 15 | } 16 | } 17 | } 18 | ], 19 | "paths": { 20 | "/cancellation/{cancelId}/approve": { 21 | "post": { 22 | "description": "Seller approves a cancellation request", 23 | "operationId": "approveCancellationRequest", 24 | "parameters": [ 25 | { 26 | "name": "cancelId", 27 | "in": "path", 28 | "description": "The unique eBay-assigned identifier of the cancellation request to be approved.", 29 | "required": true, 30 | "schema": { 31 | "type": "string" 32 | } 33 | } 34 | ], 35 | "responses": { 36 | "200": { 37 | "description": "OK" 38 | } 39 | } 40 | } 41 | }, 42 | "/cancellation/check_eligibility": { 43 | "post": { 44 | "description": "Check the eligibility of an order cancellation", 45 | "operationId": "checkCancellationEligibility", 46 | "responses": { 47 | "200": { 48 | "description": "OK" 49 | } 50 | } 51 | } 52 | }, 53 | "/cancellation/{cancelId}/confirm": { 54 | "post": { 55 | "description": "Buyer confirms the refund from a cancellation was received", 56 | "operationId": "confirmRefundReceived", 57 | "parameters": [ 58 | { 59 | "name": "cancelId", 60 | "in": "path", 61 | "description": "The unique eBay-assigned identifier of the cancellation request to be approved.", 62 | "required": true, 63 | "schema": { 64 | "type": "string" 65 | } 66 | } 67 | ], 68 | "responses": { 69 | "200": { 70 | "description": "OK" 71 | } 72 | } 73 | } 74 | }, 75 | "/cancellation": { 76 | "post": { 77 | "description": "Request or perform an order cancellation", 78 | "operationId": "createCancellation", 79 | "responses": { 80 | "200": { 81 | "description": "OK" 82 | } 83 | } 84 | } 85 | }, 86 | "/cancellation/{cancelId}": { 87 | "get": { 88 | "description": "Request or perform an order cancellation", 89 | "operationId": "getCancellation", 90 | "parameters": [ 91 | { 92 | "name": "cancelId", 93 | "in": "path", 94 | "description": "The unique eBay-assigned identifier of the cancellation request to be approved.", 95 | "required": true, 96 | "schema": { 97 | "type": "string" 98 | } 99 | } 100 | ], 101 | "responses": { 102 | "200": { 103 | "description": "OK" 104 | } 105 | } 106 | } 107 | }, 108 | "/cancellation/{cancelId}/reject": { 109 | "post": { 110 | "description": "Seller rejects a cancellation request", 111 | "operationId": "rejectCancellationRequest", 112 | "parameters": [ 113 | { 114 | "name": "cancelId", 115 | "in": "path", 116 | "description": "The unique eBay-assigned identifier of the cancellation request to be approved.", 117 | "required": true, 118 | "schema": { 119 | "type": "string" 120 | } 121 | } 122 | ], 123 | "responses": { 124 | "200": { 125 | "description": "OK" 126 | } 127 | } 128 | } 129 | }, 130 | "/cancellation/search": { 131 | "get": { 132 | "description": "Search for cancellations", 133 | "operationId": "search", 134 | "responses": { 135 | "200": { 136 | "description": "OK" 137 | } 138 | } 139 | } 140 | } 141 | } 142 | } -------------------------------------------------------------------------------- /src/types/traditional/get-all-bidders-response.ts: -------------------------------------------------------------------------------- 1 | // https://developer.ebay.com/Devzone/XML/docs/Reference/eBay/GetAllBidders.html#Output 2 | import type { 3 | CountryCodeType, 4 | CurrencyCodeType, 5 | StandardOutputFields, 6 | } from './common.js'; 7 | 8 | export interface GetAllBiddersResponse extends StandardOutputFields { 9 | BidArray: { 10 | Offer?: { 11 | Action: 12 | | 'Absentee' 13 | | 'Accept' 14 | | 'AutoCancel' 15 | | 'AutoRetraction' 16 | | 'Bid' 17 | | 'BuyItNow' 18 | | 'Cancelled' 19 | | 'Counter' 20 | | 'CustomCode' 21 | | 'Decline' 22 | | 'Offer' 23 | | 'Purchase' 24 | | 'Retraction' 25 | | 'Unknown'; 26 | ConvertedPrice: number | { value: number; currencyID: CurrencyCodeType }; 27 | Currency: CurrencyCodeType; 28 | HighestBid: number | { value: number; currencyID: CurrencyCodeType }; 29 | MaxBid: number | { value: number; currencyID: CurrencyCodeType }; 30 | MyMaxBid?: number | { value: number; currencyID: CurrencyCodeType }; 31 | Quantity: number; 32 | SecondChanceEnabled: boolean; 33 | SiteCurrency: CurrencyCodeType; 34 | TimeBid: string; 35 | User: { 36 | AboutMePage: boolean; 37 | BiddingSummary?: { 38 | BidActivityWithSeller?: number; 39 | BidRetractions?: number; 40 | BidsToUniqueCategories?: number; 41 | BidsToUniqueSellers?: number; 42 | ItemBidDetails?: { 43 | BidCount?: number; 44 | CategoryID?: string; 45 | ItemID?: string; 46 | LastBidTime?: string; 47 | SellerID?: string; 48 | }; 49 | SummaryDays?: number; 50 | TotalBids?: number; 51 | }; 52 | BuyerInfo: { 53 | ShippingAddress: { 54 | Country: CountryCodeType; 55 | PostalCode: string; 56 | }; 57 | }; 58 | Email?: string; 59 | FeedbackPrivate: boolean; 60 | FeedbackRatingStar: 61 | | 'Blue' 62 | | 'CustomCode' 63 | | 'Green' 64 | | 'GreenShooting' 65 | | 'None' 66 | | 'Purple' 67 | | 'PurpleShooting' 68 | | 'Red' 69 | | 'RedShooting' 70 | | 'SilverShooting' 71 | | 'Turquoise' 72 | | 'TurquoiseShooting' 73 | | 'Yellow' 74 | | 'YellowShooting'; 75 | FeedbackScore?: number; 76 | IDVerified: boolean; 77 | NewUser: boolean; 78 | PositiveFeedbackPercent?: number; 79 | RegistrationDate: string; 80 | Site: 81 | | 'Australia' 82 | | 'Austria' 83 | | 'Belgium_Dutch' 84 | | 'Belgium_French' 85 | | 'Canada' 86 | | 'CanadaFrench' 87 | | 'CustomCode' 88 | | 'Cyprus' 89 | | 'Czechia' 90 | | 'eBayMotors' 91 | | 'France' 92 | | 'Germany' 93 | | 'HongKong' 94 | | 'India' 95 | | 'Ireland' 96 | | 'Italy' 97 | | 'Malaysia' 98 | | 'Netherlands' 99 | | 'Philippines' 100 | | 'Poland' 101 | | 'Russia' 102 | | 'Singapore' 103 | | 'Spain' 104 | | 'Switzerland' 105 | | 'UK' 106 | | 'US'; 107 | Status: 108 | | 'AccountOnHold' 109 | | 'Confirmed' 110 | | 'CreditCardVerify' 111 | | 'CustomCode' 112 | | 'Deleted' 113 | | 'Ghost' 114 | | 'Guest' 115 | | 'InMaintenance' 116 | | 'Merged' 117 | | 'RegistrationCodeMailOut' 118 | | 'Suspended' 119 | | 'TermPending' 120 | | 'Unconfirmed' 121 | | 'Unknown'; 122 | UserAnonymized: boolean; 123 | UserID?: string; 124 | UserIDChanged: boolean; 125 | UserIDLastChanged: string; 126 | VATStatus: 'CustomCode' | 'NoVATTax' | 'VATExempt' | 'VATTax'; 127 | eBayGoodStanding: boolean; 128 | }; 129 | }; 130 | }; 131 | HighBidder: string; 132 | HighestBid: number | { value: number; currencyID: CurrencyCodeType }; 133 | ListingStatus: 'Active' | 'Completed' | 'Custom' | 'CustomCode' | 'Ended'; 134 | } 135 | -------------------------------------------------------------------------------- /src/auth/authNAuth.ts: -------------------------------------------------------------------------------- 1 | import debug from 'debug'; 2 | import Base from '../api/base.js'; 3 | import XMLRequest from '../api/traditional/XMLRequest.js'; 4 | import {IEBayApiRequest} from '../request.js'; 5 | import {AppConfig} from '../types/index.js'; 6 | 7 | const log = debug('ebay:authNAuth'); 8 | 9 | export type AuthToken = { 10 | eBayAuthToken: string, 11 | Timestamp?: string, 12 | HardExpirationTime?: string 13 | }; 14 | 15 | export default class AuthNAuth extends Base { 16 | 17 | public static readonly SIGNIN_ENDPOINT = { 18 | sandbox: 'https://signin.sandbox.ebay.com/ws/eBayISAPI.dll', 19 | production: 'https://signin.ebay.com/ws/eBayISAPI.dll' 20 | }; 21 | 22 | public static readonly API_ENDPOINT = { 23 | production: 'https://api.ebay.com/ws/api.dll', 24 | sandbox: 'https://api.sandbox.ebay.com/ws/api.dll' 25 | }; 26 | 27 | public static generateAuthUrl(sandbox: boolean, ruName: string, sessionId: string, prompt = false) { 28 | return [ 29 | sandbox ? AuthNAuth.SIGNIN_ENDPOINT.sandbox : AuthNAuth.SIGNIN_ENDPOINT.production, 30 | '?SignIn', 31 | '&RuName=', encodeURIComponent(ruName), 32 | '&SessID=', encodeURIComponent(sessionId), 33 | prompt ? '&prompt=login' : '' 34 | ].join(''); 35 | } 36 | 37 | private authToken: AuthToken | null = null; 38 | 39 | constructor(config: AppConfig, req?: IEBayApiRequest) { 40 | super(config, req); 41 | 42 | if (this.config.authToken) { 43 | this.setAuthToken(this.config.authToken); 44 | } 45 | } 46 | 47 | get apiEndpoint() { 48 | return this.config.sandbox ? AuthNAuth.API_ENDPOINT.sandbox : AuthNAuth.API_ENDPOINT.production; 49 | } 50 | 51 | /** 52 | * Generates URL for consent page landing. 53 | * 54 | * @param ruName RuName 55 | */ 56 | public async getSessionIdAndAuthUrl(ruName?: string) { 57 | if (!this.config.devId) { 58 | throw new Error('DevId is required.'); 59 | } 60 | 61 | ruName = ruName || this.config.ruName; 62 | if (!ruName) { 63 | throw new Error('RuName is required.'); 64 | } 65 | 66 | const xmlApi = new XMLRequest('GetSessionID', { 67 | RuName: ruName 68 | }, this.getRequestConfig('GetSessionID'), this.req); 69 | 70 | const data = await xmlApi.request(); 71 | 72 | log('GetSessionID data', data); 73 | 74 | return { 75 | sessionId: data.SessionID, 76 | url: AuthNAuth.generateAuthUrl(this.config.sandbox, ruName, data.SessionID) 77 | }; 78 | } 79 | 80 | public async mintToken(sessionId: string) { 81 | if (!this.config.devId) { 82 | throw new Error('DevId is required.'); 83 | } 84 | 85 | const xmlApi = new XMLRequest('FetchToken', { 86 | SessionID: sessionId 87 | }, this.getRequestConfig('FetchToken'), this.req); 88 | 89 | try { 90 | return await xmlApi.request(); 91 | } catch (error) { 92 | log('Fetch auth token failed', error); 93 | throw error; 94 | } 95 | } 96 | 97 | public async obtainToken(sessionId: string) { 98 | const token = await this.mintToken(sessionId); 99 | log('Obtain auth token', token) 100 | this.setAuthToken(token); 101 | 102 | return token; 103 | } 104 | 105 | public setAuthToken(authToken: AuthToken | string | null) { 106 | if (typeof authToken === 'string') { 107 | this.authToken = { 108 | eBayAuthToken: authToken 109 | }; 110 | } else { 111 | this.authToken = authToken; 112 | } 113 | } 114 | 115 | public getAuthToken(): AuthToken | null { 116 | if (!this.authToken) { 117 | return null; 118 | } 119 | 120 | return { 121 | ...this.authToken 122 | }; 123 | } 124 | 125 | get eBayAuthToken() { 126 | return this.authToken?.eBayAuthToken ?? null; 127 | } 128 | 129 | public getRequestConfig(callName: string) { 130 | if (typeof this.config.siteId !== 'number') { 131 | throw new Error('"siteId" is required for Auth\'n\'Auth.'); 132 | } 133 | 134 | return { 135 | useIaf: false, 136 | xmlns: 'urn:ebay:apis:eBLBaseComponents', 137 | endpoint: this.apiEndpoint, 138 | headers: { 139 | 'X-EBAY-API-CALL-NAME': callName, 140 | 'X-EBAY-API-CERT-NAME': this.config.certId, 141 | 'X-EBAY-API-APP-NAME': this.config.appId, 142 | 'X-EBAY-API-DEV-NAME': this.config.devId, 143 | 'X-EBAY-API-SITEID': this.config.siteId, 144 | 'X-EBAY-API-COMPATIBILITY-LEVEL': 967 145 | } 146 | }; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/api/apiFactory.ts: -------------------------------------------------------------------------------- 1 | import {ClientAlerts, Finding, Merchandising, Shopping, Trading} from '../types/index.js'; 2 | import Api from './index.js'; 3 | import { 4 | Browse, 5 | Buy, 6 | Deal, 7 | Feed, 8 | Marketing as BuyMarketing, 9 | MarketplaceInsights, 10 | Offer, 11 | Order 12 | } from './restful/buy/index.js'; 13 | import { 14 | Catalog, 15 | Charity, 16 | Commerce, 17 | Identity, 18 | Media, 19 | Notification, 20 | Taxonomy, 21 | Translation 22 | } from './restful/commerce/index.js'; 23 | import {Analytics as DeveloperAnalytics, Developer, KeyManagement} from './restful/developer/index.js'; 24 | import RestfulApi, {IRestful} from './restful/index.js'; 25 | import {Cancellation, Case, Inquiry, PostOrder, Return,} from './restful/postOrder/index.js'; 26 | import { 27 | AccountV1, 28 | AccountV2, 29 | Analytics as SellAnalytics, 30 | Compliance, 31 | Feed as SellFeed, 32 | Finances, 33 | Fulfillment, 34 | Inventory, 35 | Listing, 36 | Logistics, 37 | Marketing as SellMarketing, 38 | Metadata, 39 | Negotiation, 40 | Recommendation, 41 | Sell 42 | } from './restful/sell/index.js'; 43 | import Traditional from './traditional/index.js'; 44 | 45 | /** 46 | * Factory class to create RESTFul API or Traditional API. 47 | */ 48 | export default class ApiFactory extends Api { 49 | private _traditional?: Traditional; 50 | private _restful: any = {}; 51 | 52 | public createBuyApi(): Buy { 53 | return { 54 | browse: this.createRestfulApi(Browse), 55 | feed: this.createRestfulApi(Feed), 56 | marketing: this.createRestfulApi(BuyMarketing), 57 | offer: this.createRestfulApi(Offer), 58 | order: this.createRestfulApi(Order), 59 | deal: this.createRestfulApi(Deal), 60 | marketplaceInsights: this.createRestfulApi(MarketplaceInsights), 61 | }; 62 | } 63 | 64 | public createCommerceApi(): Commerce { 65 | return { 66 | catalog: this.createRestfulApi(Catalog), 67 | charity: this.createRestfulApi(Charity), 68 | identity: this.createRestfulApi(Identity), 69 | notification: this.createRestfulApi(Notification), 70 | media: this.createRestfulApi(Media), 71 | translation: this.createRestfulApi(Translation), 72 | taxonomy: this.createRestfulApi(Taxonomy), 73 | }; 74 | } 75 | 76 | public createDeveloperApi(): Developer { 77 | return { 78 | analytics: this.createRestfulApi(DeveloperAnalytics), 79 | keyManagement: this.createRestfulApi(KeyManagement), 80 | }; 81 | } 82 | 83 | public createPostOrderApi(): PostOrder { 84 | return { 85 | cancellation: this.createRestfulApi(Cancellation), 86 | case: this.createRestfulApi(Case), 87 | inquiry: this.createRestfulApi(Inquiry), 88 | return: this.createRestfulApi(Return), 89 | }; 90 | } 91 | 92 | public createSellApi(): Sell { 93 | return { 94 | account: this.createRestfulApi(AccountV1), 95 | accountV2: this.createRestfulApi(AccountV2), 96 | analytics: this.createRestfulApi(SellAnalytics), 97 | compliance: this.createRestfulApi(Compliance), 98 | fulfillment: this.createRestfulApi(Fulfillment), 99 | inventory: this.createRestfulApi(Inventory), 100 | marketing: this.createRestfulApi(SellMarketing), 101 | metadata: this.createRestfulApi(Metadata), 102 | recommendation: this.createRestfulApi(Recommendation), 103 | finances: this.createRestfulApi(Finances), 104 | feed: this.createRestfulApi(SellFeed), 105 | logistics: this.createRestfulApi(Logistics), 106 | negotiation: this.createRestfulApi(Negotiation), 107 | listing: this.createRestfulApi(Listing), 108 | }; 109 | } 110 | 111 | get traditional() { 112 | if (this._traditional) { 113 | return this._traditional; 114 | } 115 | 116 | return (this._traditional = new Traditional(this.config, this.req, this.auth)); 117 | } 118 | 119 | public createTradingApi(): Trading { 120 | return this.traditional.createTradingApi(); 121 | } 122 | 123 | public createShoppingApi(): Shopping { 124 | return this.traditional.createShoppingApi(); 125 | } 126 | 127 | public createFindingApi(): Finding { 128 | return this.traditional.createFindingApi(); 129 | } 130 | 131 | public createClientAlertsApi(): ClientAlerts { 132 | return this.traditional.createClientAlertsApi(); 133 | } 134 | 135 | public createMerchandisingApi(): Merchandising { 136 | return this.traditional.createMerchandisingApi(); 137 | } 138 | 139 | // tslint:disable-next-line:variable-name 140 | private createRestfulApi(RestfulApiClass: IRestful): T { 141 | const id = RestfulApiClass.id; 142 | return ( 143 | this._restful[id] || (this._restful[id] = new RestfulApiClass(this.config, this.req, this.auth)) 144 | ); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /test/api/restful/oas.spec.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai'; 2 | import 'mocha'; 3 | // @ts-ignore 4 | import sinon from 'sinon'; 5 | import Auth from '../../../src/auth/index.js'; 6 | import {IEBayApiRequest} from '../../../src/request.js'; 7 | 8 | import buyTests from './buy/index.js'; 9 | import commerceTests from './commerce/index.js'; 10 | import developerTests from './developer/index.js'; 11 | import postOrderTests from './postOrder/index.js'; 12 | import sellTests from './sell/index.js'; 13 | 14 | const allTests = { 15 | Buy: buyTests, 16 | Commerce: commerceTests, 17 | Developer: developerTests, 18 | Sell: sellTests, 19 | PostOrder: postOrderTests 20 | }; 21 | 22 | const appConfig = {appId: 'appId', certId: 'certId', sandbox: false, siteId: 77}; 23 | 24 | function createReq(): IEBayApiRequest { 25 | return { 26 | get: sinon.stub().returns(Promise.resolve({data: {}})), 27 | delete: sinon.stub().returns(Promise.resolve({data: {}})), 28 | put: sinon.stub().returns(Promise.resolve({data: {}})), 29 | post: sinon.stub().returns(Promise.resolve({data: {}})), 30 | postForm: sinon.stub().returns(Promise.resolve({data: {}})), 31 | instance: sinon.stub().returns(Promise.resolve({data: {}})), 32 | }; 33 | } 34 | 35 | const request = createReq(); 36 | 37 | const auth = new Auth(appConfig, request); 38 | auth.OAuth2.setClientToken({ 39 | access_token: 'token', 40 | expires_in: 1, 41 | token_type: 'test', 42 | }); 43 | 44 | describe('Open API Tests', () => { 45 | Object.entries(allTests).forEach(([name, tests]) => { 46 | describe('API > restful > ' + name, () => { 47 | // tslint:disable-next-line:variable-name 48 | tests.forEach((Oas, RestfulApi) => { 49 | it('should match name with id', () => { 50 | expect(RestfulApi.id).to.equal(RestfulApi.name); 51 | }); 52 | 53 | const api = new RestfulApi(appConfig, request, auth); 54 | 55 | if (Oas.servers) { 56 | it('"' + name + ':' + RestfulApi.name + '" should return url', () => { 57 | expect(api.baseUrl).to.oneOf( 58 | Oas.servers.map((server: any) => server.url.replace('{basePath}', server.variables.basePath.default)), 59 | ); 60 | }); 61 | 62 | it('"' + name + ':' + RestfulApi.name + '" should return correct path', () => { 63 | expect(api.basePath).to.equal( 64 | Oas.servers[0].variables.basePath.default 65 | ); 66 | }); 67 | } 68 | 69 | Object.keys(Oas.paths).forEach((path: any) => { 70 | Object.keys(Oas.paths[path]).forEach(method => { 71 | const endpoint = Oas.paths[path]; 72 | const call = endpoint[method]; 73 | if (!call.operationId || call.deprecated) { 74 | return; 75 | } 76 | const queryParams = path.match(/(?<={).+?(?=})/gi); 77 | const paramsInPath = queryParams ? queryParams : []; 78 | const paramsInHeader = call.parameters 79 | ? call.parameters.filter((p: any) => p.in === 'header') 80 | : []; 81 | const paramsInBody = (call.parameters 82 | ? call.parameters.filter((p: any) => p.in === 'body') 83 | : []).reduce((result: any, p: any) => { 84 | result[p.name] = p.name; 85 | return result; 86 | }, {}); 87 | const args = paramsInPath 88 | .map((paramName: any) => '{' + paramName + '}') 89 | .concat(paramsInHeader.map((p: any) => p.name)) 90 | .concat(paramsInBody); 91 | 92 | const req: any = createReq(); 93 | 94 | const restApi = new RestfulApi(appConfig, req, auth); 95 | 96 | it(`"${name}:${RestfulApi.name}" should implement this method (${path}). `, () => { 97 | expect(restApi[call.operationId]).to.be.a( 98 | 'function', 99 | 'AssertionError: expected to have "' + 100 | call.operationId + 101 | '" implemented.' 102 | ); 103 | }); 104 | 105 | it(`"${name}:${RestfulApi.name}:${call.operationId}" call correct method ${method} (${path}).`, () => { 106 | return restApi[call.operationId](...args).then(() => { 107 | // tslint:disable-next-line:no-unused-expression 108 | expect(req[method].calledOnce).to.be.true; 109 | }); 110 | }); 111 | 112 | it(`"${name}:${RestfulApi.name}:${call.operationId}" calls correct url (${path}).`, () => { 113 | return restApi[call.operationId](...args).then(() => { 114 | expect(decodeURI(req[method].args[0][0])).to.equal(decodeURI(encodeURI(restApi.baseUrl + path))); 115 | }); 116 | }); 117 | }); 118 | }); 119 | }); 120 | }); 121 | }); 122 | }); 123 | -------------------------------------------------------------------------------- /src/api/restful/commerce/catalog/index.ts: -------------------------------------------------------------------------------- 1 | import {CommerceCatalogSearchParams} from '../../../../types/index.js'; 2 | import {operations} from '../../../../types/restful/specs/commerce_catalog_v1_beta_oas3.js'; 3 | import Restful, {OpenApi} from '../../index.js'; 4 | 5 | /** 6 | * Use the Catalog API to search the eBay catalog for products on which to base a seller's item listing; 7 | */ 8 | export default class Catalog extends Restful implements OpenApi> { 9 | 10 | static id = 'Catalog'; 11 | 12 | get basePath(): string { 13 | return '/commerce/catalog/v1_beta'; 14 | } 15 | 16 | /** 17 | * Note: The three catalog change request methods in the Catalog API are deprecated, and are scheduled to be 18 | * decommissioned in Q1 of 2020. 19 | * 20 | * @param changeRequestId The unique identifier of the change request being requested. 21 | */ 22 | public getChangeRequest(changeRequestId: string) { 23 | return this.get(`/change_request/${changeRequestId}`); 24 | } 25 | 26 | /** 27 | * Note: The three catalog change request methods in the Catalog API are deprecated, and are scheduled to be 28 | * decommissioned in Q1 of 2020. 29 | * 30 | * @param filter One or more comma-separated criteria for narrowing down the collection of change requests returned 31 | * by this call. 32 | * @param limit The number of change requests to return. This is the result set, a subset of the full collection of 33 | * change requests that match the filter criteria of this call. 34 | * @param offset The first change request to return based on its position in the returned collection of change 35 | * requests. 36 | */ 37 | public getChangeRequests({filter, limit, offset}: { filter?: string, limit?: number, offset?: number } = {}) { 38 | return this.get(`/change_request`, { 39 | params: { 40 | filter, 41 | limit, 42 | offset 43 | } 44 | }); 45 | } 46 | 47 | /** 48 | * This call retrieves details of the catalog product identified by the eBay product identifier (ePID) specified in 49 | * the request. 50 | * 51 | * @param epid The ePID of the product being requested. 52 | */ 53 | public getProduct(epid: string) { 54 | const e = encodeURIComponent(epid); 55 | return this.get(`/product/${e}`); 56 | } 57 | 58 | /** 59 | * This call searches for and retrieves summaries of one or more products in the eBay catalog that match the search 60 | * criteria provided by a seller. 61 | * 62 | * @param params SearchCatalogParams 63 | */ 64 | public search(params?: CommerceCatalogSearchParams) { 65 | return this.get(`/product_summary/search`, { 66 | params 67 | }); 68 | } 69 | 70 | /** 71 | * This call retrieves an array of all supported aspects, aspect constraints, and aspect values for the specified 72 | * catalog product and its associated or suggested categories, as well as the values currently associated with that 73 | * product. 74 | * 75 | * @param epid The unique eBay product identifier of the catalog product that you want to update. 76 | * @param acceptLanguage This request header sets the natural language that will be provided in the field values of 77 | * the response payload. 78 | * @param otherApplicableCategoryIds Use only if you are also including the primary_category_id parameter in the 79 | * request. 80 | * @param primaryCategoryId Use only if the seller believes this product is associated with the wrong primary 81 | * category. 82 | * @param marketplaceId Use this header to specify the eBay marketplace identifier. 83 | */ 84 | public getProductMetadata(epid: string, 85 | {otherApplicableCategoryIds, primaryCategoryId}: { 86 | otherApplicableCategoryIds?: string, 87 | primaryCategoryId?: string, 88 | } = {}) { 89 | return this.get(`/get_product_metadata`, { 90 | params: { 91 | epid, 92 | other_applicable_category_ids: otherApplicableCategoryIds, 93 | primary_category_id: primaryCategoryId 94 | } 95 | }); 96 | } 97 | 98 | /** 99 | * This call retrieves an array of all supported aspects, aspect constraints, and aspect values for the specified 100 | * eBay categories. 101 | * 102 | * @param primaryCategoryId The unique identifier of the primary eBay category for which you will retrieve product 103 | * aspects. 104 | * @param otherApplicableCategoryIds A string of comma-separated category IDs. 105 | */ 106 | public getProductMetadataForCategories(primaryCategoryId: string, otherApplicableCategoryIds?: string) { 107 | return this.get(`/get_product_metadata_for_categories`, { 108 | params: { 109 | primary_category_id: primaryCategoryId, 110 | other_applicable_category_ids: otherApplicableCategoryIds 111 | } 112 | }); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/types/restful/specs/case_oas3.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file was auto-generated by openapi-typescript. 3 | * Do not make direct changes to the file. 4 | */ 5 | 6 | 7 | export interface paths { 8 | "/casemanagement/{caseId}/appeal": { 9 | /** @description Buyer or seller appeals a case decision */ 10 | post: operations["appealCaseDecision"]; 11 | }; 12 | "/casemanagement/{caseId}/close": { 13 | /** @description Buyer closes a case */ 14 | post: operations["closeCase"]; 15 | }; 16 | "/casemanagement/{caseId}": { 17 | /** @description Retrieve the details related to a specific case */ 18 | get: operations["getCase"]; 19 | }; 20 | "/casemanagement/{caseId}/issue_refund": { 21 | /** @description Seller issues a refund for a case */ 22 | post: operations["issueCaseRefund"]; 23 | }; 24 | "/casemanagement/{caseId}/provide_shipment_info": { 25 | /** @description Buyer provides return shipment information */ 26 | post: operations["provideReturnShipmentInfo"]; 27 | }; 28 | "/casemanagement/{caseId}/provide_return_address": { 29 | /** @description Seller provides a return address to the buyer */ 30 | post: operations["providesReturnAddress"]; 31 | }; 32 | "/casemanagement/search": { 33 | /** @description This call is used to search for cases using multiple filter types. */ 34 | get: operations["search"]; 35 | }; 36 | } 37 | 38 | export type webhooks = Record; 39 | 40 | export type components = Record; 41 | 42 | export type external = Record; 43 | 44 | export interface operations { 45 | 46 | /** @description Buyer or seller appeals a case decision */ 47 | appealCaseDecision: { 48 | parameters: { 49 | path: { 50 | /** @description The unique identifier of a case. This URI parameter is required in order to identify the case for which an appeal will be filed against. The case is identified by the caseId that is passed in as part of the call URI. */ 51 | caseId: string; 52 | }; 53 | }; 54 | responses: { 55 | /** @description OK */ 56 | 200: never; 57 | }; 58 | }; 59 | /** @description Buyer closes a case */ 60 | closeCase: { 61 | parameters: { 62 | path: { 63 | /** @description The unique identifier of a case. This URI parameter is required in order to identify the case for which an appeal will be filed against. The case is identified by the caseId that is passed in as part of the call URI. */ 64 | caseId: string; 65 | }; 66 | }; 67 | responses: { 68 | /** @description OK */ 69 | 200: never; 70 | }; 71 | }; 72 | /** @description Retrieve the details related to a specific case */ 73 | getCase: { 74 | parameters: { 75 | path: { 76 | /** @description The unique identifier of a case. This URI parameter is required in order to identify the case for which an appeal will be filed against. The case is identified by the caseId that is passed in as part of the call URI. */ 77 | caseId: string; 78 | }; 79 | }; 80 | responses: { 81 | /** @description OK */ 82 | 200: never; 83 | }; 84 | }; 85 | /** @description Seller issues a refund for a case */ 86 | issueCaseRefund: { 87 | parameters: { 88 | path: { 89 | /** @description The unique identifier of a case. This URI parameter is required in order to identify the case for which an appeal will be filed against. The case is identified by the caseId that is passed in as part of the call URI. */ 90 | caseId: string; 91 | }; 92 | }; 93 | responses: { 94 | /** @description OK */ 95 | 200: never; 96 | }; 97 | }; 98 | /** @description Buyer provides return shipment information */ 99 | provideReturnShipmentInfo: { 100 | parameters: { 101 | path: { 102 | /** @description The unique identifier of a case. This URI parameter is required in order to identify the case for which an appeal will be filed against. The case is identified by the caseId that is passed in as part of the call URI. */ 103 | caseId: string; 104 | }; 105 | }; 106 | responses: { 107 | /** @description OK */ 108 | 200: never; 109 | }; 110 | }; 111 | /** @description Seller provides a return address to the buyer */ 112 | providesReturnAddress: { 113 | parameters: { 114 | path: { 115 | /** @description The unique identifier of a case. This URI parameter is required in order to identify the case for which an appeal will be filed against. The case is identified by the caseId that is passed in as part of the call URI. */ 116 | caseId: string; 117 | }; 118 | }; 119 | responses: { 120 | /** @description OK */ 121 | 200: never; 122 | }; 123 | }; 124 | /** @description This call is used to search for cases using multiple filter types. */ 125 | search: { 126 | responses: { 127 | /** @description OK */ 128 | 200: never; 129 | }; 130 | }; 131 | } 132 | -------------------------------------------------------------------------------- /test/api/authNAuth.spec.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai'; 2 | import 'mocha'; 3 | // @ts-ignore 4 | import sinon from 'sinon'; 5 | import AuthNAuth from '../../src/auth/authNAuth.js'; 6 | 7 | describe('AuthNAuth', () => { 8 | const config = {appId: 'appId', certId: 'certId', sandbox: true, siteId: 0, devId: 'devId'}; 9 | let req: any = null; 10 | beforeEach(() => { 11 | req = { 12 | get: sinon.stub().returns(Promise.resolve({data: {}})), 13 | delete: sinon.stub().returns(Promise.resolve({data: {}})), 14 | put: sinon.stub().returns(Promise.resolve({data: {}})), 15 | post: sinon.stub().returns(Promise.resolve({data: {}})), 16 | postForm: sinon.stub().returns(Promise.resolve({ 17 | data: { 18 | access_token: 'new_access_token' 19 | } 20 | })), 21 | instance: sinon.stub() 22 | }; 23 | }); 24 | 25 | it('Sets the auth token', () => { 26 | const auth = new AuthNAuth({...config, authToken: 'authToken'}, req); 27 | expect(auth.getAuthToken()?.eBayAuthToken).to.equal('authToken'); 28 | }); 29 | 30 | describe('Get session id and auth url', () => { 31 | it('Throws error if devId is not defined', async () => { 32 | const auth = new AuthNAuth({...config, devId: undefined}, req); 33 | try { 34 | await auth.getSessionIdAndAuthUrl(); 35 | } catch (error: any) { 36 | expect(error.message).to.equal('DevId is required.'); 37 | } 38 | }); 39 | 40 | it('Throws error if ruName is not defined', async () => { 41 | const auth = new AuthNAuth({...config}, req); 42 | try { 43 | await auth.getSessionIdAndAuthUrl(); 44 | } catch (error: any) { 45 | expect(error.message).to.equal('RuName is required.'); 46 | } 47 | }); 48 | 49 | it('Throws error if siteId is not a Number', async () => { 50 | // @ts-ignore 51 | const auth = new AuthNAuth({...config, siteId: 'xxx', ruName: 'ruName'}, req); 52 | try { 53 | await auth.getSessionIdAndAuthUrl(); 54 | } catch (error: any) { 55 | expect(error.message).to.equal('"siteId" is required for Auth\'n\'Auth.'); 56 | } 57 | }); 58 | 59 | it('Throws error if siteId is not a Number', async () => { 60 | const post = sinon.stub().returns(Promise.resolve({ 61 | data: ` 62 | 63 | SessionID 64 | ` 65 | })); 66 | // @ts-ignore 67 | const auth = new AuthNAuth({...config, ruName: 'ruName'}, {...req, post}); 68 | 69 | const data = await auth.getSessionIdAndAuthUrl(); 70 | expect(data.sessionId).to.equal('SessionID'); 71 | expect(data.url).to.equal('https://signin.sandbox.ebay.com/ws/eBayISAPI.dll?SignIn&RuName=ruName&SessID=SessionID'); 72 | }); 73 | }); 74 | 75 | describe('Auth Token', () => { 76 | it('Throws error if devId is not defined', async () => { 77 | const auth = new AuthNAuth({...config, devId: undefined}, req); 78 | try { 79 | await auth.mintToken('SessionID'); 80 | } catch (error: any) { 81 | expect(error.message).to.equal('DevId is required.'); 82 | } 83 | }); 84 | 85 | it('fetch auth token', async () => { 86 | const post = sinon.stub().returns(Promise.resolve({ 87 | data: ` 88 | 89 | SessionID 90 | ` 91 | })); 92 | const auth = new AuthNAuth(config, {...req, post}); 93 | await auth.mintToken('SessionID'); 94 | }); 95 | 96 | it('sets and gets the token correctly', async () => { 97 | // @ts-ignore 98 | const auth = new AuthNAuth(config, req); 99 | auth.setAuthToken('authToken'); 100 | expect(auth.eBayAuthToken).to.equal('authToken'); 101 | }); 102 | }); 103 | 104 | 105 | it('Returns correct XML request config', async () => { 106 | const auth = new AuthNAuth(config, req); 107 | const xmlConfig = await auth.getRequestConfig('callName'); 108 | expect(xmlConfig).to.eql({ 109 | useIaf: false, 110 | xmlns: 'urn:ebay:apis:eBLBaseComponents', 111 | endpoint: 'https://api.sandbox.ebay.com/ws/api.dll', 112 | headers: { 113 | 'X-EBAY-API-CALL-NAME': 'callName', 114 | 'X-EBAY-API-CERT-NAME': 'certId', 115 | 'X-EBAY-API-APP-NAME': 'appId', 116 | 'X-EBAY-API-DEV-NAME': 'devId', 117 | 'X-EBAY-API-SITEID': 0, 118 | 'X-EBAY-API-COMPATIBILITY-LEVEL': 967 119 | } 120 | }); 121 | }); 122 | 123 | describe('Generate AuthUrl', () => { 124 | it('generates correct auth url', () => { 125 | const url = AuthNAuth.generateAuthUrl(false, 'ruName', 'sessionId', true); 126 | expect(url).to.equal('https://signin.ebay.com/ws/eBayISAPI.dll?SignIn&RuName=ruName&SessID=sessionId&prompt=login'); 127 | }); 128 | }); 129 | }); 130 | -------------------------------------------------------------------------------- /src/api/restful/sell/finances/index.ts: -------------------------------------------------------------------------------- 1 | import {operations} from '../../../../types/restful/specs/sell_finances_v1_oas3.js'; 2 | import Restful, {OpenApi} from '../../index.js'; 3 | 4 | /** 5 | * The Finances API is used by sellers in eBay's managed payments program to retrieve seller payout information. 6 | * 7 | * https://api.ebay.com/oauth/api_scope/sell.finances 8 | * 9 | */ 10 | export default class Finances extends Restful implements OpenApi { 11 | 12 | static id = 'Finances'; 13 | 14 | get basePath(): string { 15 | return '/sell/finances/v1'; 16 | } 17 | 18 | get subdomain(): string { 19 | return 'apiz'; 20 | } 21 | 22 | /** 23 | * Use this call to retrieve the details of a specific seller payout. 24 | * 25 | * @param payoutId The unique identifier of the payout. 26 | */ 27 | public getPayout(payoutId: string) { 28 | payoutId = encodeURIComponent(payoutId); 29 | return this.get(`/payout/${payoutId}`); 30 | } 31 | 32 | /** 33 | * Use this call to search for and retrieve one or more payout based on their payout date, 34 | * or payout status using the filter parameter. 35 | * 36 | * @param filter One or more comma-separated criteria for narrowing down the collection of payout returned by this 37 | * call. 38 | * @param limit The number of payouts to return per page of the result set. 39 | * @param offset Specifies the number of payouts to skip in the result set before returning the first payout in the 40 | * paginated response. 41 | * @param sort Allows sorting by payouts date in descending order with '-payoutDate' (default) and ascending with 'payoutDate' 42 | */ 43 | public getPayouts({ 44 | filter, 45 | limit, 46 | offset, 47 | sort, 48 | }: { 49 | filter?: string; 50 | limit?: number; 51 | offset?: number; 52 | sort?: 'payoutDate' | '-payoutDate'; 53 | } = {}) { 54 | return this.get(`/payout`, { 55 | params: { 56 | filter, 57 | limit, 58 | offset, 59 | sort, 60 | }, 61 | }); 62 | } 63 | 64 | /** 65 | * Search for and retrieve the details of multiple payouts. 66 | * * 67 | * @param filter One or more comma-separated criteria for narrowing down the collection of payout returned by this 68 | * call. 69 | */ 70 | public getPayoutSummary({ 71 | filter, 72 | }: { 73 | filter?: string; 74 | } = {}) { 75 | return this.get(`/payout_summary`, {params: {filter}}); 76 | } 77 | 78 | /** 79 | * Retrieve details of one or more monetary transactions. 80 | * @param filter One or more comma-separated criteria for narrowing down the collection of transaction returned by this 81 | * call. 82 | * @param limit The number of transaction to return per page of the result set. 83 | * @param offset Specifies the number of payouts to skip in the result set before returning the first transaction in the 84 | * paginated response. 85 | * @param sort Allows sorting by transaction date in descending order with '-transactionDate' (default) and ascending with 'transactionDate' 86 | */ 87 | public getTransactions({ 88 | filter, 89 | limit, 90 | offset, 91 | sort 92 | }: { 93 | filter?: string; 94 | limit?: number; 95 | offset?: number; 96 | sort?: 'transactionDate' | '-transactionDate', 97 | } = {}) { 98 | return this.get(`/transaction`, { 99 | params: { 100 | filter, 101 | limit, 102 | offset, 103 | sort, 104 | }, 105 | }); 106 | } 107 | 108 | /** 109 | * Retrieve total counts and values of the seller's order sales, seller credits, buyer refunds, and payment holds. 110 | * @param filter One or more comma-separated criteria for narrowing down the collection of transaction returned by this 111 | * call. 112 | * @param limit The number of transaction to return per page of the result set. 113 | */ 114 | public getTransactionSummary({ 115 | filter, 116 | }: { 117 | filter?: string; 118 | } = {}) { 119 | return this.get(`/transaction_summary`, { 120 | params: { 121 | filter, 122 | }, 123 | }); 124 | } 125 | 126 | /** 127 | * Retrieve detailed information on a TRANSFER transaction type. 128 | * 129 | * @param transferId The unique identifier of the transfer. 130 | */ 131 | public getTransfer(transferId: string) { 132 | transferId = encodeURIComponent(transferId); 133 | return this.get(`/transfer/${transferId}`); 134 | } 135 | 136 | /** 137 | * Retrieve all pending funds that have not yet been distributed through a seller payout. 138 | */ 139 | public getSellerFundsSummary() { 140 | return this.get(`/seller_funds_summary`); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/api/digitalSignature.ts: -------------------------------------------------------------------------------- 1 | import {createHash, sign} from 'crypto'; 2 | import {EBayError} from '../errors/index.js'; 3 | import {Cipher, Headers} from '../types/index.js'; 4 | 5 | const beginPrivateKey = '-----BEGIN PRIVATE KEY-----'; 6 | const endPrivateKey = '-----END PRIVATE KEY-----'; 7 | 8 | // based on https://github.com/ebay/digital-signature-nodejs-sdk 9 | 10 | /** 11 | * Returns the current UNIX timestamp. 12 | * 13 | * @returns {number} The unix timestamp. 14 | */ 15 | export const getUnixTimestamp = (): number => Math.floor(Date.now() / 1000); 16 | 17 | const getSignatureParams = (payload: any) => [ 18 | ...payload ? ['content-digest'] : [], 19 | 'x-ebay-signature-key', 20 | '@method', 21 | '@path', 22 | '@authority' 23 | ]; 24 | 25 | const getSignatureParamsValue = (payload: any) => getSignatureParams(payload).map(param => `"${param}"`).join(' '); 26 | 27 | /** 28 | * Generates the 'Content-Digest' header value for the input payload. 29 | * 30 | * @param {any} payload The request payload. 31 | * @param {string} cipher The algorithm used to calculate the digest. 32 | * @returns {string} contentDigest The 'Content-Digest' header value. 33 | */ 34 | export const generateContentDigestValue = (payload: unknown, cipher: Cipher = 'sha256'): string => { 35 | const payloadBuffer: Buffer = Buffer.from(typeof payload === 'string' ? payload : JSON.stringify(payload)); 36 | 37 | const hash = createHash(cipher).update(payloadBuffer).digest('base64'); 38 | const algo: string = cipher === 'sha512' ? 'sha-512' : 'sha-256'; 39 | return `${algo}=:${hash}:`; 40 | }; 41 | 42 | export type SignatureComponents = { 43 | method: string 44 | authority: string // the host 45 | path: string 46 | } 47 | 48 | /** 49 | * Generates the base string. 50 | * 51 | * @param {any} headers The HTTP request headers. 52 | * @param {SignatureComponents} signatureComponents The config. 53 | * @param {any} payload The payload. 54 | * @param {number} timestamp The timestamp. 55 | * @returns {string} payload The base string. 56 | */ 57 | export function generateBaseString(headers: Headers, signatureComponents: SignatureComponents, payload: any, timestamp = getUnixTimestamp()): string { 58 | try { 59 | let baseString: string = ''; 60 | const signatureParams: string[] = getSignatureParams(payload); 61 | 62 | signatureParams.forEach(param => { 63 | baseString += `"${param.toLowerCase()}": `; 64 | 65 | if (param.startsWith('@')) { 66 | switch (param.toLowerCase()) { 67 | case '@method': 68 | baseString += signatureComponents.method; 69 | break; 70 | case '@authority': 71 | baseString += signatureComponents.authority; 72 | break; 73 | case '@path': 74 | baseString += signatureComponents.path; 75 | break; 76 | default: 77 | throw new Error('Unknown pseudo header ' + param); 78 | } 79 | } else { 80 | if (!headers[param]) { 81 | throw new Error('Header ' + param + ' not included in message'); 82 | } 83 | baseString += headers[param]; 84 | } 85 | 86 | baseString += '\n'; 87 | }); 88 | 89 | baseString += `"@signature-params": (${getSignatureParamsValue(payload)});created=${timestamp}`; 90 | 91 | return baseString; 92 | } catch (error: any) { 93 | throw new EBayError(`Error calculating signature base: ${error.message}`); 94 | } 95 | } 96 | 97 | /** 98 | * Generates the Signature-Input header value for the input payload. 99 | * 100 | * @param {any} payload The input config. 101 | * @param {number} timestamp The timestamp. 102 | * @returns {string} the 'Signature-Input' header value. 103 | */ 104 | export const generateSignatureInput = (payload: any, timestamp = getUnixTimestamp()): string => `sig1=(${getSignatureParamsValue(payload)});created=${timestamp}`; 105 | 106 | /** 107 | * Generates the 'Signature' header. 108 | * 109 | * @param {any} headers The HTTP headers. 110 | * @param {string} privateKey The HTTP headers. 111 | * @param {SignatureComponents} signatureComponents The signature components 112 | * @param {any} payload The payload 113 | * @param {number} timestamp The payload 114 | * @returns {string} the signature header value. 115 | */ 116 | export function generateSignature( 117 | headers: any, 118 | privateKey: string, 119 | signatureComponents: SignatureComponents, 120 | payload: any, 121 | timestamp = getUnixTimestamp() 122 | ): string { 123 | const baseString = generateBaseString(headers, signatureComponents, payload, timestamp); 124 | 125 | privateKey = privateKey.trim(); 126 | if (!privateKey.startsWith(beginPrivateKey)) { 127 | privateKey = beginPrivateKey + '\n' + privateKey + '\n' + endPrivateKey; 128 | } 129 | 130 | const signatureBuffer = sign( 131 | undefined, // If algorithm is undefined, then it is dependent upon the private key type. 132 | Buffer.from(baseString), 133 | privateKey 134 | ); 135 | 136 | const signature = signatureBuffer.toString('base64'); 137 | return `sig1=:${signature}:`; 138 | } 139 | 140 | -------------------------------------------------------------------------------- /src/api/restful/postOrder/inquiry/index.ts: -------------------------------------------------------------------------------- 1 | import Restful from '../../index.js'; 2 | import { 3 | BuyerCloseInquiryRequest, 4 | CheckInquiryEligibilityRequest, 5 | CreateInquiryRequest, 6 | EscalateInquiryRequest, 7 | InquirySearchParams, 8 | InquiryVoluntaryRefundRequest, 9 | SellerProvideRefundInfoRequest, 10 | SendMessageRequest, 11 | ShipmentInfoRequest 12 | } from '../../../../types/index.js'; 13 | 14 | /** 15 | * Post-Order Inquiry API 16 | */ 17 | export default class Inquiry extends Restful { 18 | 19 | static id = 'Inquiry'; 20 | 21 | get basePath(): string { 22 | return '/post-order/v2'; 23 | } 24 | 25 | get useIaf() { 26 | return true; 27 | } 28 | 29 | /** 30 | * Check if a buyer is eligible to open an inquiry on an order. 31 | * 32 | * @param payload the CheckInquiryEligibilityRequest 33 | */ 34 | public checkInquiryEligibility(payload: CheckInquiryEligibilityRequest) { 35 | return this.post(`/inquiry/check_eligibility`, payload); 36 | } 37 | 38 | /** 39 | * Close an inquiry for the buyer 40 | * 41 | * @param inquiryId The unique ID of the inquiry to be closed. 42 | * @param payload the BuyerCloseInquiryRequest 43 | */ 44 | public closeInquiry(inquiryId: string, payload?: BuyerCloseInquiryRequest) { 45 | inquiryId = encodeURIComponent(inquiryId); 46 | if (typeof payload?.closeReason === 'string') { 47 | payload.closeReason = payload.closeReason.trim(); 48 | } 49 | return this.post(`/inquiry/${inquiryId}/close`, payload); 50 | } 51 | 52 | /** 53 | * Buyer confirms the refund from an inquiry was received 54 | * 55 | * @param inquiryId The unique identifier of a case. 56 | */ 57 | public confirmInquiryRefund(inquiryId: string) { 58 | inquiryId = encodeURIComponent(inquiryId); 59 | return this.post(`/inquiry/${inquiryId}/confirm_refund`); 60 | } 61 | 62 | /** 63 | * Create an inquiry for the buyer. 64 | * 65 | * @param payload the CreateInquiryRequest 66 | */ 67 | public createInquiry(payload: CreateInquiryRequest) { 68 | if (typeof payload.desiredOutcome === 'string') { 69 | payload.desiredOutcome = payload.desiredOutcome.trim(); 70 | } 71 | return this.post(`/inquiry`, payload); 72 | } 73 | 74 | /** 75 | * Escalate an inquiry to an INR case. 76 | * 77 | * @param inquiryId the unique identifier of the inquiry to be escalated. 78 | * @param payload the EscalateInquiryRequest 79 | */ 80 | public escalateInquiry(inquiryId: string, payload: EscalateInquiryRequest) { 81 | inquiryId = encodeURIComponent(inquiryId); 82 | payload.escalateInquiryReason = payload.escalateInquiryReason.trim(); 83 | return this.post(`/inquiry/${inquiryId}/escalate`, payload); 84 | } 85 | 86 | /** 87 | * Retrieve the history and details related to a specific inquiry. 88 | * 89 | * @param inquiryId the unique ID of the inquiry for which details and history are to be retrieved. 90 | */ 91 | public getInquiry(inquiryId: string) { 92 | inquiryId = encodeURIComponent(inquiryId); 93 | return this.get(`/inquiry/${inquiryId}`); 94 | } 95 | 96 | /** 97 | * Issue a refund for an inquiry. 98 | * 99 | * @param inquiryId the unique ID of the inquiry for which a refund is to be issued. 100 | * @param payload the InquiryVoluntaryRefundRequest 101 | */ 102 | public issueInquiryRefund(inquiryId: string, payload?: InquiryVoluntaryRefundRequest) { 103 | inquiryId = encodeURIComponent(inquiryId); 104 | return this.post(`/inquiry/${inquiryId}/issue_refund`, payload); 105 | } 106 | 107 | /** 108 | * Provide refund information about an inquiry to the buyer. 109 | * 110 | * @param inquiryId The unique ID of the inquiry for which to provide refund information. 111 | * @param payload the InquiryVoluntaryRefundRequest 112 | */ 113 | public provideInquiryRefundInfo(inquiryId: string, payload: SellerProvideRefundInfoRequest) { 114 | inquiryId = encodeURIComponent(inquiryId); 115 | return this.post(`/inquiry/${inquiryId}/provide_refund_info`, payload); 116 | } 117 | 118 | /** 119 | * Provide shipment information for an inquiry. 120 | * 121 | * @param inquiryId The unique ID of the inquiry for which to provide shipment information. 122 | * @param payload the ShipmentInfoRequest 123 | */ 124 | public provideInquiryShipmentInfo(inquiryId: string, payload?: ShipmentInfoRequest) { 125 | inquiryId = encodeURIComponent(inquiryId); 126 | return this.post(`/inquiry/${inquiryId}/provide_shipment_info`, payload); 127 | } 128 | 129 | /** 130 | * This call is used to search for inquiries using multiple filter types. 131 | * 132 | * @param params the InquirySearchParams 133 | */ 134 | public search(params?: InquirySearchParams) { 135 | return this.get(`/inquiry/search`, { 136 | params 137 | }); 138 | } 139 | 140 | /** 141 | * Contact the buyer or seller about an inquiry. 142 | * 143 | * @param inquiryId The unique ID of the inquiry being discussed. 144 | * @param payload the SendMessageRequest 145 | */ 146 | public sendInquiryMessage(inquiryId: string, payload: SendMessageRequest) { 147 | inquiryId = encodeURIComponent(inquiryId); 148 | return this.post(`/inquiry/${inquiryId}/send_message`, payload); 149 | } 150 | } 151 | --------------------------------------------------------------------------------