1 Star 0 Fork 0

wengo / go-amazon

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
checkout.go 25.90 KB
一键复制 编辑 原始数据 按行查看 历史
wengooooo 提交于 2022-08-08 19:48 . update
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
package amazon
import (
"fmt"
"gitee.com/wengo/go-mamba"
"github.com/PuerkitoBio/goquery"
"github.com/tidwall/gjson"
"io/ioutil"
"net/url"
"regexp"
"strconv"
"strings"
"time"
)
// 判断是否选择收货地址页面
func (a *Amazon) IsSelectAddressPage(resp *mamba.Response, document *goquery.Document) bool {
return resp.Header().Get("x-amz-checkout-url") == "/gp/buy/billingaddressselect/handlers/display.html" ||
document.Find("a[href^='/gp/buy/addressselect/handlers/continue.html']").Length() > 0 ||
document.Find("#address-ui-checkout-form").Length() > 0
}
func (a *Amazon) IsNeedRedirectIemSelectPage(resp *mamba.Response) bool {
//{"isclienttimebased":1,"requestid":"BBCX1ZD4B26P1HXEP352","conductoraction":{"url":"/gp/buy/itemselect/handlers/display.html?useCase=multiAddress","type":"redirect"}}
return gjson.Get(resp.String(), "conductoraction.url").String() != "" && gjson.Get(resp.String(), "conductoraction.type").String() != "" && strings.Contains(gjson.Get(resp.String(), "conductoraction.url").String(), "/gp/buy/itemselect")
}
func (a *Amazon) IsNeedRedirectSharedPage(resp *mamba.Response) bool {
//{"isclienttimebased":1,"requestid":"08BFFDWGQXS3BNV9XJ4Q","conductoraction":{"url":"/gp/buy/shared/handlers/dispatch.html?hasWorkingJavascript=1","type":"redirect"}}
return gjson.Get(resp.String(), "conductoraction.url").String() != "" && gjson.Get(resp.String(), "conductoraction.type").String() != "" && strings.Contains(gjson.Get(resp.String(), "conductoraction.url").String(), "/gp/buy/shared")
}
// 判断是否商品送货到该地址
func (a *Amazon) IsItemSelectPage(document *goquery.Document) bool {
return document.Find("#changeQuantityFormId").Length() > 0
}
// 判断是否无法送货到该地址
func (a *Amazon) IsSoldOutPage(document *goquery.Document) bool {
return document.Find(".turbo-checkout-padding").Length() > 0 || document.Find("#oos #doc #important-message-box").Length() > 0
}
// 判断是否下单成功
func (a *Amazon) IsPlaceOrderSuccess(document *goquery.Document) bool {
return document.Find("#widget-purchaseConfirmationDetails").Length() > 0
}
// 判断是否可以有收货地址可选
func (a *Amazon) CanSelectAddress(document *goquery.Document) bool {
return document.Find("#address-list").Length() > 0 || document.Find("a[href*='/gp/buy/addressselect/handlers/continue.html']").Length() > 0
}
// 判断是否可以选择信用卡
func (a *Amazon) CanSelectCreditCard(document *goquery.Document) bool {
return document.Find(".pmts-cc-detail-row").Length() > 1
}
// 判断是否可以选择信用卡
func (a *Amazon) CanSelectCheque(document *goquery.Document) bool {
if document.Find(".pmts-bank-account-row").Length() == 0 {
html, _ := document.Html()
ioutil.WriteFile("payment.html", []byte(html), 0644)
}
return document.Find(".pmts-bank-account-row").Length() > 1
}
// 判断是否可以选择支票
func (a *Amazon) CanSelectChecking(document *goquery.Document) bool {
return document.Find(".pmts-bank-account-row").Length() > 0
}
func (a *Amazon) IsCartPage(document *goquery.Document) bool {
return document.Find("#gutterCartViewForm").Length() > 0
}
// 选择收货地址
func (a *Amazon) SelectAddress(document *goquery.Document) (resp *mamba.Response, newDocument *goquery.Document, err error) {
if document.Find("#address-list").Length() > 0 {
//html, _ := document.Html()
//ioutil.WriteFile(fmt.Sprintf("shipping-%d.html", time.Now().Unix()), []byte(html), 0644)
_, method, formData, err := a.ExtractFormData(document, "#address-list")
parse, _ := url.Parse(formData["submissionURL"])
for key, value := range parse.Query() {
formData[key] = value[0]
}
formData["hasWorkingJavascript"] = "1"
formData["isClientTimeBased"] = "1"
formData["handler"] = "/gp/buy/addressselect/handlers/continue.html"
if err != nil {
return nil, nil, err
}
resp, newDocument, err = a.Submit(`/gp/buy/shared/handlers/async-continue.html/ref=chk_addr_select_1_customer`, method, nil, nil, formData)
} else {
link, _ := document.Find("a[href*='/gp/buy/addressselect/handlers/continue.html']").Attr("href")
if link != "" {
resp, newDocument, err = a.Navigate(link)
}
}
return
}
// 创建收货地址
func (a *Amazon) SubmitCheckoutAddress(address AddressSuggestions, document *goquery.Document) (resp *mamba.Response, newDocument *goquery.Document, err error) {
_, method, shippingFormData, err := a.ExtractFormData(document, "#address-ui-checkout-form")
if err != nil {
return nil, nil, fmt.Errorf("提取收货地址表单错误, %s", err.Error())
}
purchaseId, _ := document.Find("input[name='purchaseId']").Attr("value")
var currentCountry string
document.Find("#address-ui-widgets-countryCode-dropdown-nativeId").ChildrenFiltered(`option`).EachWithBreak(func(i int, selection *goquery.Selection) bool {
_, selected := selection.Attr("selected")
if selected {
currentCountry, _ = selection.Attr("value")
shippingFormData["address-ui-widgets-countryCode"] = currentCountry
return false
}
return true
})
shippingFormData["purchaseId"] = purchaseId
shippingFormData["address-ui-widgets-enterAddressFullName"] = address.Recipient
shippingFormData["address-ui-widgets-enterAddressPhoneNumber"] = address.Phone
shippingFormData["address-ui-widgets-enterAddressLine1"] = address.AddressLine1
shippingFormData["address-ui-widgets-enterAddressLine2"] = address.AddressLine2
shippingFormData["address-ui-widgets-enterAddressCity"] = address.City
if document.Find("#address-ui-widgets-enterAddressStateOrRegion-dropdown-nativeId").Length() > 0 {
shippingFormData["address-ui-widgets-enterAddressStateOrRegion"] = address.StateOrRegion
}
shippingFormData["address-ui-widgets-enterAddressPostalCode"] = address.PostalCode
shippingFormData["address-ui-widgets-use-as-my-default"] = "true"
// 创建地址
resp, newDocument, _ = a.Submit(`/a/addresses/ajax/widgets/create`, method, nil, nil, shippingFormData)
// 获取addressId
addressId := gjson.Get(resp.String(), "createOrEditAddressResponse.addressId").String()
htmlContent := gjson.Get(resp.String(), "createOrEditAddressResponse.html").String()
if addressId == "" && htmlContent != "" {
document, _ = goquery.NewDocumentFromReader(strings.NewReader(htmlContent))
_, _, verifyAddressForm, err := a.ExtractFormData(document, "#address-ui-widgets-enterAddressFormContainer")
if err != nil {
return nil, nil, err
}
verifyAddressForm["address-ui-widgets-suggested-address-selection"] = verifyAddressForm["address-ui-widgets-suggested-address-selection_#radio2#"]
delete(verifyAddressForm, "address-ui-widgets-suggested-address-selection_#radio2#")
delete(verifyAddressForm, "address-ui-widgets-editOriginalOrSuggestedAddress")
delete(verifyAddressForm, "address-ui-widgets-editOriginalOrSuggestedAddress_#radio3#")
verifyAddressForm["address-ui-widgets-delivery-instructions-data"] = fmt.Sprintf(`{"initialCountryCode":"%s"}`, currentCountry)
verifyAddressForm["purchaseId"] = purchaseId
resp, newDocument, _ = a.Submit(`/a/addresses/ajax/widgets/create`, POST, nil, nil, verifyAddressForm)
addressId = gjson.Get(resp.String(), "createOrEditAddressResponse.addressId").String()
}
// 跳转到下一步
resp, newDocument, err = a.Submit(`/gp/buy/shared/handlers/async-continue.html/ref=ox_shipaddress_add_new_addr`, POST, nil, nil, map[string]string{
"action": "select-shipping",
"addressID": addressId,
"purchaseId": purchaseId,
"isClientTimeBased": "1",
"handler": "/gp/buy/addressselect/handlers/continue.html",
})
return
}
// 获取checkout的cc表单
func (a *Amazon) GetCheckOutCreditCardForm(document *goquery.Document) (resp *mamba.Response, newDocument *goquery.Document, err error) {
html, _ := document.Html()
matcher := regexp.MustCompile(`"secureFormTarget":"(ApxSecureIframe-pp-[\w]+-[\d]+)"`)
matchResult := matcher.FindAllStringSubmatch(html, -1)
var frameName string
if len(matchResult) > 0 {
frameName = matchResult[0][1]
}
matcher = regexp.MustCompile(`"parentWidgetInstanceId":"([\w]+)"`)
matchResult = matcher.FindAllStringSubmatch(html, -1)
var parentWidgetInstanceId string
if len(matchResult) > 0 {
parentWidgetInstanceId = matchResult[0][1]
}
widgetState, _ := document.Find("input[name='ppw-widgetState']").Attr("value")
if widgetState == "" {
matcher = regexp.MustCompile(`"serializedState":"([^"]+)"`)
matchResult = matcher.FindAllStringSubmatch(html, -1)
if len(matchResult) > 0 {
widgetState = matchResult[0][1]
}
}
paymentInfo := map[string]string{
"widgetState": widgetState,
"returnUrl": "/gp/buy/payselect/handlers/apx-submit-continue.html",
//"clientId":"YA:Wallet", //1
"clientId": "Checkout",
"usePopover": "true",
"maxAgeSeconds": "7200",
"iFrameName": frameName,
"parentWidgetInstanceId": parentWidgetInstanceId,
"hideAddPaymentInstrumentHeader": "true",
"creatablePaymentMethods": "CC",
}
parseBaseUrl, _ := url.Parse(a.client.BaseURL)
code := strings.Split(parseBaseUrl.Hostname(), ".")
resp, newDocument, err = a.Submit(fmt.Sprintf(`https://apx-security.%s/cpe/pm/register`, strings.Join(code[1:], ".")), POST, nil, nil, paymentInfo)
return
}
// 提交cc表单
func (a *Amazon) SubmitCheckoutCreditCard(recipient, cardNo, cvv, valid string, document *goquery.Document) (resp *mamba.Response, newDocument *goquery.Document, err error) {
action, method, paymentFormData, err := a.ExtractFormData(document, "form[id^='pp-']")
if err != nil {
return nil, nil, fmt.Errorf("提交CC表单 %s", err)
}
html, _ := document.Html()
var customerId string
matcher := regexp.MustCompile(`"customerId":"([^"]+)"`)
matchResult := matcher.FindAllStringSubmatch(html, -1)
if len(matchResult) > 0 {
customerId = matchResult[0][1]
}
validDate := strings.Split(valid, "/")
//paymentFormData["addCreditCardNumber"] = "5374561980970006"
/*
4485375628832141
5566751569499315
5405032032986039
4556633059034973
5334416841435294
5539799574999278
*/
//paymentFormData["addCreditCardNumber"] = "5514075212288989"
//paymentFormData["addCreditCardNumber"] = "5365504303810047"
//paymentFormData["addCreditCardNumber"] = "4556025397359842"
//paymentFormData["addCreditCardNumber"] = "4539412852660660" //websdk验证方法
//paymentFormData["addCreditCardNumber"] = "4293416035783691"
paymentFormData["addCreditCardNumber"] = cardNo
if _, ok := paymentFormData["addCreditCardVerificationNumber"]; ok {
paymentFormData["addCreditCardVerificationNumber"] = cvv
}
paymentFormData["ppw-accountHolderName"] = recipient
paymentFormData["ppw-expirationDate_month"] = validDate[0]
paymentFormData["ppw-expirationDate_year"] = validDate[1]
paymentFormData["ppw-jsEnabled"] = "true"
//parseBaseUrl, _ := url.Parse(a.client.BaseURL)
//code := strings.Split(parseBaseUrl.Hostname(), ".")
//tld := strings.Join(code[1:], ".")
code, tld := GetCodeAndTld(a.client.BaseURL)
var sifProfile string
switch code[len(code)-1] {
case "com", "ca":
sifProfile = "APX-Encrypt-All-NA"
case "au":
sifProfile = "APX-Encrypt-All-FE"
case "de", "uk":
sifProfile = "APX-Encrypt-All-EU"
}
action = fmt.Sprintf(`https://apx-security.%s/payments-portal/data/f1/widgets2/v1/customer/%s/continueWidget?sif_profile=%s`, tld, customerId, sifProfile)
resp, document, err = a.Submit(action, method, nil, nil, paymentFormData)
if err != nil {
return resp, document, fmt.Errorf("提交信用卡信息错误")
}
if strings.Contains(resp.String(), "addCreditCardNumber") {
return resp, nil, fmt.Errorf("信用卡无效, 结果为 %s", resp.String())
}
//if gjson.Get(resp.String(), "additionalWidgetResponseData.additionalData.widgetDone").String() != "true" {
// return resp, document, fmt.Errorf("提交信用卡信息不正确, 结果为 %s", resp.String())
//}
return
}
func (a *Amazon) VerifyCreditCard(resp *mamba.Response, document *goquery.Document) (newResp *mamba.Response, newDocument *goquery.Document, err error) {
html, _ := document.Html()
matcher := regexp.MustCompilePOSIX(`"customerId":"([^"]+)"`)
customerId := matcher.FindAllStringSubmatch(html, -1)
matcher = regexp.MustCompilePOSIX(`"serializedState":"([^"]+)"`)
widgetState := matcher.FindAllStringSubmatch(html, -1)
if len(customerId) > 0 && len(widgetState) > 0 {
formData := map[string]string{
"ppw-jsEnabled": "true",
"ppw-widgetEvent": "GetRedirectUrlEvent",
"ppw-javaEnabled": "false",
"ppw-widgetState": widgetState[0][1],
"ppw-language": "zh-CN",
"ppw-screenColorDepth": "24",
"ppw-screenHeight": "1440",
//"ppw-screenWidth": "2206",
"ppw-screenWidth": "2560",
"ppw-timeZone": "-480",
}
index := 0
for {
newResp, newDocument, err = a.Ajax(fmt.Sprintf(`/payments-portal/data/widgets2/v1/customer/%s/continueWidget`, customerId[0][1]), POST, map[string]interface{}{
"Widget-Ajax-Attempt-Count": strconv.Itoa(index),
"executions-widget-ajax-continue-attempt-count": "0",
}, nil, formData)
formData["ppw-widgetState"] = gjson.Get(newResp.String(), "additionalWidgetResponseData.additionalData.widgetState").String()
index++
if gjson.Get(newResp.String(), "additionalWidgetResponseData.additionalData.challengeRenderer").String() == "WebSDK" {
return nil, nil, fmt.Errorf("WebSDK的验证方式无法进行验证")
}
if gjson.Get(newResp.String(), "additionalWidgetResponseData.additionalData.authenticationStatus").String() != "" {
break
}
if index > 10 {
return nil, nil, fmt.Errorf("无法验证验证信用卡")
}
time.Sleep(3 * time.Second)
}
//resp, newDocument, err = a.Ajax(fmt.Sprintf(`/payments-portal/data/widgets2/v1/customer/%s/continueWidget`, customerId[0][1]), POST, map[string]interface{}{"Widget-Ajax-Attempt-Count": "0"}, nil, formData)
//ioutil.WriteFile("cc-1.html", resp.Body(), 0644)
//formData["ppw-widgetState"] = gjson.Get(resp.String(), "additionalWidgetResponseData.additionalData.widgetState").String()
//resp, newDocument, err = a.Ajax(fmt.Sprintf(`/payments-portal/data/widgets2/v1/customer/%s/continueWidget`, customerId[0][1]), POST, map[string]interface{}{"Widget-Ajax-Attempt-Count": "0"}, nil, formData)
//ioutil.WriteFile("cc-2.html", resp.Body(), 0644)
switch gjson.Get(newResp.String(), "additionalWidgetResponseData.additionalData.authenticationStatus").String() {
case "DECLINED":
return nil, nil, fmt.Errorf("银行拒绝此张信用卡")
default:
action := "/cpe/executions"
uri, _ := url.Parse(resp.Request.URL)
startWidgetContextId := uri.Query().Get("startWidgetContextId")
queryData := map[string]string{
"ppw-terminalState": "SUCCESS",
"ppw-reason": gjson.Get(resp.String(), "additionalWidgetResponseData.additionalData.reason").String(),
"ppw-authenticateSourceId": gjson.Get(resp.String(), "additionalWidgetResponseData.additionalData.sourceId").String(),
"ppw-clientId": gjson.Get(resp.String(), "additionalWidgetResponseData.additionalData.clientId").String(),
"ppw-maybeRemainingBalance": "",
"ppw-maybeChargeIdempotencyKey": "",
"pw-widgetEvent": "TerminalStatusEvent",
"ppw-widgetState": widgetState[0][1],
"startWidgetContextId": startWidgetContextId,
"contextKey": customerId[0][1],
}
newResp, newDocument, err = a.Submit(action, GET, nil, queryData, nil)
return newResp, newDocument, err
}
}
return nil, nil, fmt.Errorf("验证信用卡页面无法找到customerId")
}
// 获取checkout的支票表单
func (a *Amazon) GetCheckOutCheckingForm(document *goquery.Document) (newDocument *goquery.Document, err error) {
html, _ := document.Html()
matcher := regexp.MustCompile(`"secureFormTarget":"(ApxSecureIframe-pp-[\w]+-[\d]+)"`)
matchResult := matcher.FindAllStringSubmatch(html, -1)
var frameName string
if len(matchResult) > 0 {
frameName = matchResult[0][1]
}
matcher = regexp.MustCompile(`"parentWidgetInstanceId":"([\w]+)"`)
matchResult = matcher.FindAllStringSubmatch(html, -1)
var parentWidgetInstanceId string
if len(matchResult) > 0 {
parentWidgetInstanceId = matchResult[0][1]
}
widgetState, _ := document.Find("input[name='ppw-widgetState']").Attr("value")
if widgetState == "" {
matcher = regexp.MustCompile(`"serializedState":"([^"]+)"`)
matchResult = matcher.FindAllStringSubmatch(html, -1)
if len(matchResult) > 0 {
widgetState = matchResult[0][1]
}
}
paymentInfo := map[string]string{
"widgetState": widgetState,
"returnUrl": "/gp/buy/payselect/handlers/apx-submit-continue.html",
//"clientId":"YA:Wallet", //1
"usePopover": "true",
"maxAgeSeconds": "7200",
"iFrameName": frameName,
"parentWidgetInstanceId": parentWidgetInstanceId,
"hideAddPaymentInstrumentHeader": "true",
"creatablePaymentMethods": "BA",
}
_, tld := GetCodeAndTld(a.client.BaseURL)
_, newDocument, err = a.Submit(fmt.Sprintf(`https://apx-security.%s/cpe/pm/register`, tld), POST, nil, nil, paymentInfo)
return
}
// 提交支票表单
func (a *Amazon) SubmitCheckoutChecking(accountHolderName, bankAccountRouting, bankAccountNumber, bankAccountDriversLicense, licenseIssuedState string, document *goquery.Document) (resp *mamba.Response, err error) {
action, method, checkingFormData, err := a.ExtractFormData(document, ".pmts-compact-add-bank-account-form")
if err != nil {
return nil, fmt.Errorf("提交支票表单 %s", err)
}
for key, _ := range checkingFormData {
if strings.Contains(key, "#radio") {
delete(checkingFormData, key)
}
}
html, _ := document.Html()
var customerId string
matcher := regexp.MustCompile(`"customerId":"([^"]+)"`)
matchResult := matcher.FindAllStringSubmatch(html, -1)
if len(matchResult) > 0 {
customerId = matchResult[0][1]
}
checkingFormData["ppw-widgetEvent:AddBankAccountEvent"] = ""
checkingFormData["ppw-accountHolderName"] = accountHolderName
checkingFormData["addBankAccountRoutingNumber"] = bankAccountRouting
checkingFormData["addBankAccountNumber"] = bankAccountNumber
checkingFormData["confirmBankAccountNumber"] = bankAccountNumber
checkingFormData["addBankAccountDriversLicense"] = bankAccountDriversLicense
checkingFormData["ppw-licenseIssuedState"] = licenseIssuedState
checkingFormData["ppw-jsEnabled"] = "true"
code, tld := GetCodeAndTld(a.client.BaseURL)
var sifProfile string
switch code[len(code)-1] {
case "com", "ca":
sifProfile = "APX-Encrypt-All-NA"
case "au":
sifProfile = "APX-Encrypt-All-FE"
case "de", "uk":
sifProfile = "APX-Encrypt-All-EU"
}
action = fmt.Sprintf(`https://apx-security.%s/payments-portal/data/f1/widgets2/v1/customer/%s/continueWidget?sif_profile=%s`, tld, customerId, sifProfile)
//action = fmt.Sprintf(`https://apx-security.amazon.com/payments-portal/data/f1/widgets2/v1/customer/%s/continueWidget?sif_profile=APX-Encrypt-All-NA`, customerId)
resp, _, err = a.Ajax(action, method, nil, nil, checkingFormData)
if err != nil {
return resp, fmt.Errorf("提交支票错误")
}
//if gjson.Get(resp.String(), "additionalWidgetResponseData.additionalData.widgetDone").String() != "true" {
// return resp, fmt.Errorf("提交信用卡信息不正确, 结果为 %s", resp.String())
//}
return
}
// 提交银行表单
func (a *Amazon) SubmitCheckoutBank(accountHolderName, bankAccountRouting, bankAccountNumber string, document *goquery.Document) (resp *mamba.Response, err error) {
action, method, checkingFormData, err := a.ExtractFormData(document, ".pmts-compact-add-bank-account-form")
if err != nil {
return nil, fmt.Errorf("提交银行表单 %s", err)
}
for key, _ := range checkingFormData {
if strings.Contains(key, "#radio") {
delete(checkingFormData, key)
}
}
html, _ := document.Html()
var customerId string
matcher := regexp.MustCompile(`"customerId":"([^"]+)"`)
matchResult := matcher.FindAllStringSubmatch(html, -1)
if len(matchResult) > 0 {
customerId = matchResult[0][1]
}
checkingFormData["ppw-widgetEvent:AddBankAccountEvent"] = ""
checkingFormData["ppw-accountHolderName"] = accountHolderName
checkingFormData["addBankAccountRoutingNumber"] = bankAccountRouting
checkingFormData["addBankAccountNumber"] = bankAccountNumber
//checkingFormData["ppw-storageConsent"] = "OptedOut"
checkingFormData["ppw-storageConsent"] = "OptedIn"
checkingFormData["ppw-jsEnabled"] = "true"
code, tld := GetCodeAndTld(a.client.BaseURL)
var sifProfile string
switch code[len(code)-1] {
case "com", "ca":
sifProfile = "APX-Encrypt-All-NA"
case "au":
sifProfile = "APX-Encrypt-All-FE"
case "de", "uk":
sifProfile = "APX-Encrypt-All-EU"
}
action = fmt.Sprintf(`https://apx-security.%s/payments-portal/data/f1/widgets2/v1/customer/%s/continueWidget?sif_profile=%s`, tld, customerId, sifProfile)
//action = fmt.Sprintf(`https://apx-security.amazon.com/payments-portal/data/f1/widgets2/v1/customer/%s/continueWidget?sif_profile=APX-Encrypt-All-EU`, customerId)
resp, _, err = a.Ajax(action, method, nil, nil, checkingFormData)
if err != nil {
return resp, fmt.Errorf("提交银行卡信息错误")
}
//if gjson.Get(resp.String(), "additionalWidgetResponseData.additionalData.widgetDone").String() != "true" {
// return resp, fmt.Errorf("提交信用卡信息不正确, 结果为 %s", resp.String())
//}
return
}
// 选择付款方式
func (a *Amazon) SelectPaymentMethod(document *goquery.Document) (resp *mamba.Response, newDocument *goquery.Document, err error) {
action, method, formData, err := a.ExtractFormData(document, ".pmts-select-payment-instrument-form")
if err != nil {
return nil, nil, fmt.Errorf(`选择付款方式步骤 -> %s`, err.Error())
}
for key, _ := range formData {
if strings.Contains(key, "#radio") {
delete(formData, key)
}
}
formData["ppw-claimCode"] = ""
formData["ppw-jsEnabled"] = "true"
formData["ppw-widgetEvent:SetPaymentPlanSelectContinueEvent"] = ""
if document.Find("#nav-bar").Length() == 0 {
formData["isAsync"] = "1" // 德国的下单界面有一页checkout和分页checkout的界面, 如果是一页checkout的话,需要加上
}
formData["isClientTimeBased"] = "1"
formData["handler"] = "/gp/buy/payselect/handlers/apx-submit-continue.html"
if len(formData) > 0 {
resp, newDocument, err = a.Submit(action, method, nil, nil, formData)
} else {
return nil, nil, fmt.Errorf("无法选择信用卡")
}
return
}
// 判断是否选择付款方式页面
func (a *Amazon) IsSelectPaymentMethodPage(resp *mamba.Response, document *goquery.Document) bool {
return resp.Header().Get("x-amz-checkout-url") == "/gp/buy/payselect/handlers/display.html" ||
document.Find(".pmts-select-payment-instrument-form").Length() > 0
}
// 判断是否选择付款方式页面
func (a *Amazon) IsPrimePage(document *goquery.Document) bool {
return document.Find(".prime-nothanks-button").Length() > 0
}
// 判断是否选择付款方式页面
func (a *Amazon) NotNeedPrime(document *goquery.Document) (resp *mamba.Response, newDocument *goquery.Document, err error) {
link, _ := document.Find(".prime-nothanks-button").Attr("href")
resp, newDocument, err = a.Navigate(link)
return
}
// 判断是否选择付款方式页面
func (a *Amazon) IsPlaceOrderdPage(document *goquery.Document) bool {
return document.Find("#spc-form").Length() > 0
}
// 建立订单
func (a *Amazon) PlaceOrder(document *goquery.Document) (resp *mamba.Response, newDocument *goquery.Document, err error) {
action, method, placeOrderFormData, err := a.ExtractFormData(document, "#spc-form")
if err != nil {
return nil, nil, fmt.Errorf("完成订单 %s", err)
}
placeOrderFormData["setOrderingPrefs"] = "1"
placeOrderFormData["purchaseLevelMessageIds"] = "saveDefaults"
placeOrderFormData["submitFromSPC"] = "1"
//一页checkout
placeOrderFormData["useCtb"] = "1"
placeOrderFormData["javaEnabled"] = "false"
placeOrderFormData["language"] = "zh-CN"
placeOrderFormData["screenColorDepth"] = "24"
placeOrderFormData["screenHeight"] = "1440"
placeOrderFormData["screenWidth"] = "2560"
placeOrderFormData["timeZone"] = "-480"
placeOrderFormData["hasWorkingJavascript"] = "1"
placeOrderFormData["placeYourOrder1"] = "1"
placeOrderFormData["needsThirdPartyRedirect"] = "1"
placeOrderFormData["paymentDisplayName"] = "Visa/Delta/Electron"
placeOrderFormData["isfirsttimecustomer"] = "0"
placeOrderFormData["isTFXEligible"] = ""
placeOrderFormData["isFxEnabled"] = ""
placeOrderFormData["isFXTncShown"] = ""
resp, newDocument, err = a.Submit(action, method, nil, nil, placeOrderFormData)
return
}
func (a *Amazon) IsCheckoutAddressIntercept(document *goquery.Document) bool {
return document.Find(".checkout-addressintercept").Length() > 0
}
func (a *Amazon) IsCompleteOrderPage(document *goquery.Document) bool {
_, exists := document.Find("meta").Attr("content")
return exists
}
// 完成订单,获取订单号
func (a *Amazon) CompleteOrder(document *goquery.Document) (resp *mamba.Response, newDocument *goquery.Document, err error) {
content, exists := document.Find("meta").Attr("content")
if exists {
completeUrl := strings.ReplaceAll(content, "0; url=", "")
return a.Navigate(completeUrl)
}
//else if document.Find("#typ-reviewYourAllOrders").Length() > 0 {
// return resp, document, err
//}
// You cannot buy this item because it's out of stock
return nil, nil, fmt.Errorf("无法提取执行下单链接, 可能该商品库存不足")
}
// 是需要确认是下一个重复的订单
func (a *Amazon) IsNeedConfirmOrder(document *goquery.Document) bool {
return document.Find("form[data-action='handle-dup-order']").Length() > 0
}
// 再次确认下单
func (a *Amazon) ConfirmOrder(document *goquery.Document) (resp *mamba.Response, newDocument *goquery.Document, err error) {
action, method, formData, err := a.ExtractFormData(document, "form[data-action='handle-dup-order']")
if err != nil {
return nil, nil, err
}
delete(formData, "cancelOrder")
resp, newDocument, err = a.Submit(action, method, nil, nil, formData)
if err != nil {
return resp, newDocument, fmt.Errorf("无法确认订单")
}
//resp, newDocument, err = a.CompleteOrder(newDocument)
return
}
1
https://gitee.com/wengo/go-amazon.git
git@gitee.com:wengo/go-amazon.git
wengo
go-amazon
go-amazon
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891