TransactionTest.php 219 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621
  1. <?php
  2. namespace Test\Integration;
  3. require_once dirname(__DIR__) . '/Setup.php';
  4. use DateTime;
  5. use Test;
  6. use Test\Setup;
  7. use Test\Braintree\CreditCardNumbers\CardTypeIndicators;
  8. use Braintree;
  9. class TransactionTest extends Setup
  10. {
  11. public function testCloneTransaction()
  12. {
  13. $result = Braintree\Transaction::sale([
  14. 'amount' => '100.00',
  15. 'orderId' => '123',
  16. 'creditCard' => [
  17. 'number' => '5105105105105100',
  18. 'expirationDate' => '05/2011',
  19. ],
  20. 'customer' => [
  21. 'firstName' => 'Dan',
  22. ],
  23. 'billing' => [
  24. 'firstName' => 'Carl',
  25. ],
  26. 'shipping' => [
  27. 'firstName' => 'Andrew',
  28. ]
  29. ]);
  30. $this->assertTrue($result->success);
  31. $transaction = $result->transaction;
  32. $cloneResult = Braintree\Transaction::cloneTransaction(
  33. $transaction->id,
  34. [
  35. 'amount' => '123.45',
  36. 'channel' => 'MyShoppingCartProvider',
  37. 'options' => ['submitForSettlement' => false]
  38. ]
  39. );
  40. Test\Helper::assertPrintable($cloneResult);
  41. $this->assertTrue($cloneResult->success);
  42. $cloneTransaction = $cloneResult->transaction;
  43. $this->assertEquals('Dan', $cloneTransaction->customerDetails->firstName);
  44. $this->assertEquals('Carl', $cloneTransaction->billingDetails->firstName);
  45. $this->assertEquals('Andrew', $cloneTransaction->shippingDetails->firstName);
  46. $this->assertEquals('510510******5100', $cloneTransaction->creditCardDetails->maskedNumber);
  47. $this->assertEquals('authorized', $cloneTransaction->status);
  48. $this->assertEquals('123.45', $cloneTransaction->amount);
  49. $this->assertEquals('MyShoppingCartProvider', $cloneTransaction->channel);
  50. }
  51. public function testCreateTransactionUsingNonce()
  52. {
  53. $http = new HttpClientApi(Braintree\Configuration::$global);
  54. $nonce = $http->nonce_for_new_card([
  55. "creditCard" => [
  56. "number" => "4111111111111111",
  57. "expirationMonth" => "11",
  58. "expirationYear" => "2099"
  59. ],
  60. "share" => true
  61. ]);
  62. $result = Braintree\Transaction::sale([
  63. 'amount' => '47.00',
  64. 'paymentMethodNonce' => $nonce
  65. ]);
  66. $this->assertTrue($result->success);
  67. $transaction = $result->transaction;
  68. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  69. $this->assertEquals(Braintree\Transaction::SALE, $transaction->type);
  70. $this->assertEquals('47.00', $transaction->amount);
  71. }
  72. public function testGatewayCreateTransactionUsingNonce()
  73. {
  74. $http = new HttpClientApi(Braintree\Configuration::$global);
  75. $nonce = $http->nonce_for_new_card([
  76. "creditCard" => [
  77. "number" => "4111111111111111",
  78. "expirationMonth" => "11",
  79. "expirationYear" => "2099"
  80. ],
  81. "share" => true
  82. ]);
  83. $gateway = new Braintree\Gateway([
  84. 'environment' => 'development',
  85. 'merchantId' => 'integration_merchant_id',
  86. 'publicKey' => 'integration_public_key',
  87. 'privateKey' => 'integration_private_key'
  88. ]);
  89. $result = $gateway->transaction()->sale([
  90. 'amount' => '47.00',
  91. 'paymentMethodNonce' => $nonce
  92. ]);
  93. $this->assertTrue($result->success);
  94. $transaction = $result->transaction;
  95. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  96. $this->assertEquals(Braintree\Transaction::SALE, $transaction->type);
  97. $this->assertEquals('47.00', $transaction->amount);
  98. }
  99. public function testSaleWithIdealPaymentId()
  100. {
  101. $result = Braintree\Transaction::sale([
  102. 'amount' => '100.00',
  103. 'merchantAccountId' => 'ideal_merchant_account',
  104. 'paymentMethodNonce' => Test\Helper::generateValidIdealPaymentId(),
  105. 'orderId' => 'ABC123',
  106. 'options' => [
  107. 'submitForSettlement' => true,
  108. ]
  109. ]);
  110. $this->assertTrue($result->success);
  111. $transaction = $result->transaction;
  112. $this->assertEquals(Braintree\Transaction::SETTLED, $transaction->status);
  113. $this->assertEquals(Braintree\Transaction::SALE, $transaction->type);
  114. $this->assertEquals(Braintree\PaymentInstrumentType::IDEAL_PAYMENT, $transaction->paymentInstrumentType);
  115. $this->assertEquals('100.00', $transaction->amount);
  116. $this->assertRegExp('/^idealpayment_\w{6,}$/', $transaction->idealPayment->idealPaymentId);
  117. $this->assertRegExp('/^\d{16,}$/', $transaction->idealPayment->idealTransactionId);
  118. $this->assertRegExp('/^https:\/\//', $transaction->idealPayment->imageUrl);
  119. $this->assertNotNull($transaction->idealPayment->maskedIban);
  120. $this->assertNotNull($transaction->idealPayment->bic);
  121. }
  122. public function testSaleAndSkipAdvancedFraudChecking()
  123. {
  124. $gateway = Test\Helper::advancedFraudIntegrationMerchantGateway();
  125. $result = $gateway->transaction()->sale([
  126. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  127. 'creditCard' => [
  128. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  129. 'expirationDate' => '05/2009',
  130. ],
  131. 'options' => [
  132. 'skipAdvancedFraudChecking' => true
  133. ]
  134. ]);
  135. $this->assertTrue($result->success);
  136. $transaction = $result->transaction;
  137. $this->assertFalse(property_exists($transaction, "riskData"));
  138. }
  139. public function testSaleAndSkipAvs()
  140. {
  141. $result = Braintree\Transaction::sale([
  142. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  143. 'creditCard' => [
  144. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  145. 'expirationDate' => '05/2019',
  146. ],
  147. 'options' => [
  148. 'skipAvs' => true
  149. ]
  150. ]);
  151. $this->assertTrue($result->success);
  152. $transaction = $result->transaction;
  153. $this->assertNull($transaction->avsErrorResponseCode);
  154. $this->assertEquals($transaction->avsStreetAddressResponseCode, 'B');
  155. }
  156. public function testSaleAndSkipCvv()
  157. {
  158. $result = Braintree\Transaction::sale([
  159. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  160. 'creditCard' => [
  161. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  162. 'expirationDate' => '05/2019',
  163. ],
  164. 'options' => [
  165. 'skipCvv' => true
  166. ]
  167. ]);
  168. $this->assertTrue($result->success);
  169. $transaction = $result->transaction;
  170. $this->assertEquals($transaction->cvvResponseCode, 'B');
  171. }
  172. public function testSaleWithLevel3SummaryFields()
  173. {
  174. $result = Braintree\Transaction::sale([
  175. 'amount' => '35.05',
  176. 'creditCard' => [
  177. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  178. 'expirationDate' => '05/2009',
  179. ],
  180. 'shippingAmount' => '1.00',
  181. 'discountAmount' => '2.00',
  182. 'shipsFromPostalCode' => '12345',
  183. ]);
  184. $this->assertTrue($result->success);
  185. $transaction = $result->transaction;
  186. $this->assertEquals('1.00', $transaction->shippingAmount);
  187. $this->assertEquals('2.00', $transaction->discountAmount);
  188. $this->assertEquals('12345', $transaction->shipsFromPostalCode);
  189. }
  190. public function testSaleWhenDiscountAmountFormatIsInvalid()
  191. {
  192. $result = Braintree\Transaction::sale([
  193. 'amount' => '35.05',
  194. 'creditCard' => [
  195. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  196. 'expirationDate' => '05/2009',
  197. ],
  198. 'discountAmount' => '123.456',
  199. ]);
  200. $this->assertFalse($result->success);
  201. $baseErrors = $result->errors->forKey('transaction')->onAttribute('discountAmount');
  202. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_DISCOUNT_AMOUNT_FORMAT_IS_INVALID, $baseErrors[0]->code);
  203. }
  204. public function testSaleWhenDiscountAmountCannotBeNegative()
  205. {
  206. $result = Braintree\Transaction::sale([
  207. 'amount' => '35.05',
  208. 'creditCard' => [
  209. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  210. 'expirationDate' => '05/2009',
  211. ],
  212. 'discountAmount' => '-2.00',
  213. ]);
  214. $this->assertFalse($result->success);
  215. $baseErrors = $result->errors->forKey('transaction')->onAttribute('discountAmount');
  216. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_DISCOUNT_AMOUNT_CANNOT_BE_NEGATIVE, $baseErrors[0]->code);
  217. }
  218. public function testSaleWhenDiscountAmountIsTooLarge()
  219. {
  220. $result = Braintree\Transaction::sale([
  221. 'amount' => '35.05',
  222. 'creditCard' => [
  223. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  224. 'expirationDate' => '05/2009',
  225. ],
  226. 'discountAmount' => '2147483647',
  227. ]);
  228. $this->assertFalse($result->success);
  229. $baseErrors = $result->errors->forKey('transaction')->onAttribute('discountAmount');
  230. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_DISCOUNT_AMOUNT_IS_TOO_LARGE, $baseErrors[0]->code);
  231. }
  232. public function testSaleWhenShippingAmountFormatIsInvalid()
  233. {
  234. $result = Braintree\Transaction::sale([
  235. 'amount' => '35.05',
  236. 'creditCard' => [
  237. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  238. 'expirationDate' => '05/2009',
  239. ],
  240. 'shippingAmount' => '1a00',
  241. ]);
  242. $this->assertFalse($result->success);
  243. $baseErrors = $result->errors->forKey('transaction')->onAttribute('shippingAmount');
  244. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_SHIPPING_AMOUNT_FORMAT_IS_INVALID, $baseErrors[0]->code);
  245. }
  246. public function testSaleWhenShippingAmountCannotBeNegative()
  247. {
  248. $result = Braintree\Transaction::sale([
  249. 'amount' => '35.05',
  250. 'creditCard' => [
  251. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  252. 'expirationDate' => '05/2009',
  253. ],
  254. 'shippingAmount' => '-1.00',
  255. ]);
  256. $this->assertFalse($result->success);
  257. $baseErrors = $result->errors->forKey('transaction')->onAttribute('shippingAmount');
  258. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_SHIPPING_AMOUNT_CANNOT_BE_NEGATIVE, $baseErrors[0]->code);
  259. }
  260. public function testSaleWhenShippingAmountIsTooLarge()
  261. {
  262. $result = Braintree\Transaction::sale([
  263. 'amount' => '35.05',
  264. 'creditCard' => [
  265. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  266. 'expirationDate' => '05/2009',
  267. ],
  268. 'shippingAmount' => '2147483647',
  269. ]);
  270. $this->assertFalse($result->success);
  271. $baseErrors = $result->errors->forKey('transaction')->onAttribute('shippingAmount');
  272. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_SHIPPING_AMOUNT_IS_TOO_LARGE, $baseErrors[0]->code);
  273. }
  274. public function testSaleWhenShipsFromPostalCodeIsTooLong()
  275. {
  276. $result = Braintree\Transaction::sale([
  277. 'amount' => '35.05',
  278. 'creditCard' => [
  279. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  280. 'expirationDate' => '05/2009',
  281. ],
  282. 'shipsFromPostalCode' => '12345678901',
  283. ]);
  284. $this->assertFalse($result->success);
  285. $baseErrors = $result->errors->forKey('transaction')->onAttribute('shipsFromPostalCode');
  286. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_SHIPS_FROM_POSTAL_CODE_IS_TOO_LONG, $baseErrors[0]->code);
  287. }
  288. public function testSaleWhenShipsFromPostalCodeIsInvalid()
  289. {
  290. $result = Braintree\Transaction::sale([
  291. 'amount' => '35.05',
  292. 'creditCard' => [
  293. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  294. 'expirationDate' => '05/2009',
  295. ],
  296. 'shipsFromPostalCode' => [1, 2, 3],
  297. ]);
  298. $this->assertFalse($result->success);
  299. $baseErrors = $result->errors->forKey('transaction')->onAttribute('shipsFromPostalCode');
  300. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_SHIPS_FROM_POSTAL_CODE_IS_INVALID, $baseErrors[0]->code);
  301. }
  302. public function testSaleWhenShipsFromPostalCodeInvalidCharacters()
  303. {
  304. $result = Braintree\Transaction::sale([
  305. 'amount' => '35.05',
  306. 'creditCard' => [
  307. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  308. 'expirationDate' => '05/2009',
  309. ],
  310. 'shipsFromPostalCode' => '1$345',
  311. ]);
  312. $this->assertFalse($result->success);
  313. $baseErrors = $result->errors->forKey('transaction')->onAttribute('shipsFromPostalCode');
  314. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_SHIPS_FROM_POSTAL_CODE_INVALID_CHARACTERS, $baseErrors[0]->code);
  315. }
  316. public function testSale_withLineItemsZero()
  317. {
  318. $result = Braintree\Transaction::sale([
  319. 'amount' => '45.15',
  320. 'creditCard' => [
  321. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  322. 'expirationDate' => '05/2009',
  323. ]
  324. ]);
  325. $this->assertTrue($result->success);
  326. $transaction = $result->transaction;
  327. $lineItems = $transaction->lineItems();
  328. $this->assertEquals(0, sizeof($lineItems));
  329. }
  330. public function testSale_withLineItemsSingleOnlyRequiredFields()
  331. {
  332. $result = Braintree\Transaction::sale([
  333. 'amount' => '35.05',
  334. 'creditCard' => [
  335. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  336. 'expirationDate' => '05/2009',
  337. ],
  338. 'lineItems' => [[
  339. 'quantity' => '1.0232',
  340. 'name' => 'Name #1',
  341. 'kind' => Braintree\TransactionLineItem::DEBIT,
  342. 'unitAmount' => '45.1232',
  343. 'totalAmount' => '45.15',
  344. ]]
  345. ]);
  346. $this->assertTrue($result->success);
  347. $transaction = $result->transaction;
  348. $lineItems = $transaction->lineItems();
  349. $this->assertEquals(1, sizeof($lineItems));
  350. $lineItem = $lineItems[0];
  351. $this->assertEquals('1.0232', $lineItem->quantity);
  352. $this->assertEquals('Name #1', $lineItem->name);
  353. $this->assertEquals(Braintree\TransactionLineItem::DEBIT, $lineItem->kind);
  354. $this->assertEquals('45.1232', $lineItem->unitAmount);
  355. $this->assertEquals('45.15', $lineItem->totalAmount);
  356. }
  357. public function testSale_withLineItemsSingleZeroAmounts()
  358. {
  359. $result = Braintree\Transaction::sale([
  360. 'amount' => '35.05',
  361. 'creditCard' => [
  362. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  363. 'expirationDate' => '05/2009',
  364. ],
  365. 'lineItems' => [[
  366. 'quantity' => '1.0232',
  367. 'name' => 'Name #1',
  368. 'kind' => Braintree\TransactionLineItem::DEBIT,
  369. 'unitAmount' => '45.1232',
  370. 'totalAmount' => '45.15',
  371. 'discountAmount' => '0',
  372. 'taxAmount' => '0',
  373. 'unitTaxAmount' => '0',
  374. ]]
  375. ]);
  376. $this->assertTrue($result->success);
  377. $transaction = $result->transaction;
  378. $lineItems = $transaction->lineItems();
  379. $this->assertEquals(1, sizeof($lineItems));
  380. $lineItem = $lineItems[0];
  381. $this->assertEquals('1.0232', $lineItem->quantity);
  382. $this->assertEquals('Name #1', $lineItem->name);
  383. $this->assertEquals(Braintree\TransactionLineItem::DEBIT, $lineItem->kind);
  384. $this->assertEquals('45.1232', $lineItem->unitAmount);
  385. $this->assertEquals('45.15', $lineItem->totalAmount);
  386. $this->assertEquals('0', $lineItem->discountAmount);
  387. $this->assertEquals('0', $lineItem->taxAmount);
  388. $this->assertEquals('0', $lineItem->unitTaxAmount);
  389. }
  390. public function testSale_withLineItemsSingle()
  391. {
  392. $result = Braintree\Transaction::sale([
  393. 'amount' => '45.15',
  394. 'creditCard' => [
  395. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  396. 'expirationDate' => '05/2009',
  397. ],
  398. 'lineItems' => [[
  399. 'quantity' => '1.0232',
  400. 'name' => 'Name #1',
  401. 'description' => 'Description #1',
  402. 'kind' => Braintree\TransactionLineItem::DEBIT,
  403. 'unitAmount' => '45.1232',
  404. 'unitTaxAmount' => '1.23',
  405. 'unitOfMeasure' => 'gallon',
  406. 'discountAmount' => '1.02',
  407. 'taxAmount' => '4.50',
  408. 'totalAmount' => '45.15',
  409. 'productCode' => '23434',
  410. 'commodityCode' => '9SAASSD8724',
  411. 'url' => 'https://example.com/products/23434',
  412. ]]
  413. ]);
  414. $this->assertTrue($result->success);
  415. $transaction = $result->transaction;
  416. $lineItems = $transaction->lineItems();
  417. $this->assertEquals(1, sizeof($lineItems));
  418. $lineItem = $lineItems[0];
  419. $this->assertEquals('1.0232', $lineItem->quantity);
  420. $this->assertEquals('Name #1', $lineItem->name);
  421. $this->assertEquals('Description #1', $lineItem->description);
  422. $this->assertEquals(Braintree\TransactionLineItem::DEBIT, $lineItem->kind);
  423. $this->assertEquals('45.1232', $lineItem->unitAmount);
  424. $this->assertEquals('1.23', $lineItem->unitTaxAmount);
  425. $this->assertEquals('gallon', $lineItem->unitOfMeasure);
  426. $this->assertEquals('1.02', $lineItem->discountAmount);
  427. $this->assertEquals('4.50', $lineItem->taxAmount);
  428. $this->assertEquals('45.15', $lineItem->totalAmount);
  429. $this->assertEquals('23434', $lineItem->productCode);
  430. $this->assertEquals('9SAASSD8724', $lineItem->commodityCode);
  431. $this->assertEquals('https://example.com/products/23434', $lineItem->url);
  432. }
  433. public function testSale_withLineItemsMultiple()
  434. {
  435. $result = Braintree\Transaction::sale([
  436. 'amount' => '35.05',
  437. 'creditCard' => [
  438. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  439. 'expirationDate' => '05/2009',
  440. ],
  441. 'lineItems' => [
  442. [
  443. 'quantity' => '1.0232',
  444. 'name' => 'Name #1',
  445. 'description' => 'Description #1',
  446. 'kind' => Braintree\TransactionLineItem::DEBIT,
  447. 'unitAmount' => '45.1232',
  448. 'unitOfMeasure' => 'gallon',
  449. 'discountAmount' => '1.02',
  450. 'taxAmount' => '4.50',
  451. 'totalAmount' => '45.15',
  452. 'productCode' => '23434',
  453. 'commodityCode' => '9SAASSD8724',
  454. ],
  455. [
  456. 'quantity' => '2.02',
  457. 'name' => 'Name #2',
  458. 'description' => 'Description #2',
  459. 'kind' => Braintree\TransactionLineItem::CREDIT,
  460. 'unitAmount' => '5',
  461. 'unitOfMeasure' => 'gallon',
  462. 'totalAmount' => '45.15',
  463. ]
  464. ]
  465. ]);
  466. $this->assertTrue($result->success);
  467. $transaction = $result->transaction;
  468. $lineItems = $transaction->lineItems();
  469. $this->assertEquals(2, sizeof($lineItems));
  470. $lineItem1 = null;
  471. foreach ($lineItems as $lineItem) {
  472. if ($lineItem->name == 'Name #1') {
  473. $lineItem1 = $lineItem;
  474. break;
  475. }
  476. }
  477. if ($lineItem1 == null) {
  478. $this->fail('TransactionLineItem with name \'Name #1\' not returned.');
  479. }
  480. $this->assertEquals('1.0232', $lineItem1->quantity);
  481. $this->assertEquals('Name #1', $lineItem1->name);
  482. $this->assertEquals('Description #1', $lineItem1->description);
  483. $this->assertEquals(Braintree\TransactionLineItem::DEBIT, $lineItem1->kind);
  484. $this->assertEquals('45.1232', $lineItem1->unitAmount);
  485. $this->assertEquals('gallon', $lineItem1->unitOfMeasure);
  486. $this->assertEquals('1.02', $lineItem1->discountAmount);
  487. $this->assertEquals('4.50', $lineItem1->taxAmount);
  488. $this->assertEquals('45.15', $lineItem1->totalAmount);
  489. $this->assertEquals('23434', $lineItem1->productCode);
  490. $this->assertEquals('9SAASSD8724', $lineItem1->commodityCode);
  491. $lineItem2 = null;
  492. foreach ($lineItems as $lineItem) {
  493. if ($lineItem->name == 'Name #2') {
  494. $lineItem2 = $lineItem;
  495. break;
  496. }
  497. }
  498. if ($lineItem2 == null) {
  499. $this->fail('TransactionLineItem with name \'Name #2\' not returned.');
  500. }
  501. $this->assertEquals('2.02', $lineItem2->quantity);
  502. $this->assertEquals('Name #2', $lineItem2->name);
  503. $this->assertEquals('Description #2', $lineItem2->description);
  504. $this->assertEquals(Braintree\TransactionLineItem::CREDIT, $lineItem2->kind);
  505. $this->assertEquals('5', $lineItem2->unitAmount);
  506. $this->assertEquals('gallon', $lineItem2->unitOfMeasure);
  507. $this->assertEquals('45.15', $lineItem2->totalAmount);
  508. $this->assertEquals(null, $lineItem2->discountAmount);
  509. $this->assertEquals(null, $lineItem2->taxAmount);
  510. $this->assertEquals(null, $lineItem2->productCode);
  511. $this->assertEquals(null, $lineItem2->commodityCode);
  512. }
  513. public function testSale_withLineItemsValidationErrorCommodityCodeIsTooLong()
  514. {
  515. $result = Braintree\Transaction::sale([
  516. 'amount' => '35.05',
  517. 'creditCard' => [
  518. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  519. 'expirationDate' => '05/2009',
  520. ],
  521. 'lineItems' => [
  522. [
  523. 'quantity' => '1.0232',
  524. 'name' => 'Name #1',
  525. 'kind' => Braintree\TransactionLineItem::DEBIT,
  526. 'unitAmount' => '45.1232',
  527. 'unitOfMeasure' => 'gallon',
  528. 'discountAmount' => '1.02',
  529. 'taxAmount' => '4.50',
  530. 'totalAmount' => '45.15',
  531. 'productCode' => '23434',
  532. 'commodityCode' => '9SAASSD8724',
  533. ],
  534. [
  535. 'quantity' => '1.0232',
  536. 'name' => 'Name #2',
  537. 'kind' => Braintree\TransactionLineItem::DEBIT,
  538. 'unitAmount' => '45.1232',
  539. 'unitOfMeasure' => 'gallon',
  540. 'discountAmount' => '1.02',
  541. 'taxAmount' => '4.50',
  542. 'totalAmount' => '45.15',
  543. 'productCode' => '23434',
  544. 'commodityCode' => '0123456789123',
  545. ]
  546. ]
  547. ]);
  548. $this->assertFalse($result->success);
  549. $this->assertEquals(
  550. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_COMMODITY_CODE_IS_TOO_LONG,
  551. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('commodityCode')[0]->code
  552. );
  553. }
  554. public function testSale_withLineItemsValidationErrorDescriptionIsTooLong()
  555. {
  556. $result = Braintree\Transaction::sale([
  557. 'amount' => '35.05',
  558. 'creditCard' => [
  559. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  560. 'expirationDate' => '05/2009',
  561. ],
  562. 'lineItems' => [
  563. [
  564. 'quantity' => '1.0232',
  565. 'name' => 'Name #1',
  566. 'kind' => Braintree\TransactionLineItem::DEBIT,
  567. 'unitAmount' => '45.1232',
  568. 'unitOfMeasure' => 'gallon',
  569. 'discountAmount' => '1.02',
  570. 'taxAmount' => '4.50',
  571. 'totalAmount' => '45.15',
  572. 'productCode' => '23434',
  573. 'commodityCode' => '9SAASSD8724',
  574. ],
  575. [
  576. 'quantity' => '1.0232',
  577. 'name' => 'Name #2',
  578. 'description' => "This is a line item description which is far too long. Like, way too long to be practical. We don't like how long this line item description is.",
  579. 'kind' => Braintree\TransactionLineItem::DEBIT,
  580. 'unitAmount' => '45.1232',
  581. 'unitOfMeasure' => 'gallon',
  582. 'discountAmount' => '1.02',
  583. 'taxAmount' => '4.50',
  584. 'totalAmount' => '45.15',
  585. 'productCode' => '23434',
  586. 'commodityCode' => '9SAASSD8724',
  587. ]
  588. ]
  589. ]);
  590. $this->assertFalse($result->success);
  591. $this->assertEquals(
  592. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_DESCRIPTION_IS_TOO_LONG,
  593. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('description')[0]->code
  594. );
  595. }
  596. public function testSale_withLineItemsValidationErrorDiscountAmountIsTooLarge()
  597. {
  598. $result = Braintree\Transaction::sale([
  599. 'amount' => '35.05',
  600. 'creditCard' => [
  601. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  602. 'expirationDate' => '05/2009',
  603. ],
  604. 'lineItems' => [
  605. [
  606. 'quantity' => '1.0232',
  607. 'name' => 'Name #1',
  608. 'kind' => Braintree\TransactionLineItem::DEBIT,
  609. 'unitAmount' => '45.1232',
  610. 'unitOfMeasure' => 'gallon',
  611. 'discountAmount' => '1.02',
  612. 'taxAmount' => '4.50',
  613. 'totalAmount' => '45.15',
  614. 'productCode' => '23434',
  615. 'commodityCode' => '9SAASSD8724',
  616. ],
  617. [
  618. 'quantity' => '1.0232',
  619. 'name' => 'Name #2',
  620. 'kind' => Braintree\TransactionLineItem::DEBIT,
  621. 'unitAmount' => '45.1232',
  622. 'unitOfMeasure' => 'gallon',
  623. 'discountAmount' => '2147483648',
  624. 'taxAmount' => '4.50',
  625. 'totalAmount' => '45.15',
  626. 'productCode' => '23434',
  627. 'commodityCode' => '9SAASSD8724',
  628. ]
  629. ]
  630. ]);
  631. $this->assertFalse($result->success);
  632. $this->assertEquals(
  633. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_DISCOUNT_AMOUNT_IS_TOO_LARGE,
  634. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('discountAmount')[0]->code
  635. );
  636. }
  637. public function testSale_withLineItemsValidationErrorDiscountAmountCannotBeNegative()
  638. {
  639. $result = Braintree\Transaction::sale([
  640. 'amount' => '35.05',
  641. 'creditCard' => [
  642. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  643. 'expirationDate' => '05/2009',
  644. ],
  645. 'lineItems' => [
  646. [
  647. 'quantity' => '1.0232',
  648. 'name' => 'Name #1',
  649. 'kind' => Braintree\TransactionLineItem::DEBIT,
  650. 'unitAmount' => '45.1232',
  651. 'unitOfMeasure' => 'gallon',
  652. 'discountAmount' => '1.02',
  653. 'taxAmount' => '4.50',
  654. 'totalAmount' => '45.15',
  655. 'productCode' => '23434',
  656. 'commodityCode' => '9SAASSD8724',
  657. ],
  658. [
  659. 'quantity' => '1.0232',
  660. 'name' => 'Name #2',
  661. 'kind' => Braintree\TransactionLineItem::DEBIT,
  662. 'unitAmount' => '45.1232',
  663. 'unitOfMeasure' => 'gallon',
  664. 'discountAmount' => '-2',
  665. 'taxAmount' => '4.50',
  666. 'totalAmount' => '45.15',
  667. 'productCode' => '23434',
  668. 'commodityCode' => '9SAASSD8724',
  669. ]
  670. ]
  671. ]);
  672. $this->assertFalse($result->success);
  673. $this->assertEquals(
  674. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_DISCOUNT_AMOUNT_CANNOT_BE_NEGATIVE,
  675. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('discountAmount')[0]->code
  676. );
  677. }
  678. public function testSale_withLineItemsValidationErrorTaxAmountFormatIsInvalid()
  679. {
  680. $result = Braintree\Transaction::sale([
  681. 'amount' => '35.05',
  682. 'creditCard' => [
  683. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  684. 'expirationDate' => '05/2009',
  685. ],
  686. 'lineItems' => [
  687. [
  688. 'quantity' => '1.0232',
  689. 'name' => 'Name #1',
  690. 'kind' => Braintree\TransactionLineItem::DEBIT,
  691. 'unitAmount' => '45.1232',
  692. 'unitOfMeasure' => 'gallon',
  693. 'discountAmount' => '1.02',
  694. 'taxAmount' => '4.511',
  695. 'totalAmount' => '45.15',
  696. 'productCode' => '23434',
  697. 'commodityCode' => '9SAASSD8724',
  698. ],
  699. ],
  700. ]);
  701. $this->assertFalse($result->success);
  702. $this->assertEquals(
  703. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_TAX_AMOUNT_FORMAT_IS_INVALID,
  704. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index0')->onAttribute('taxAmount')[0]->code
  705. );
  706. }
  707. public function testSale_withLineItemsValidationErrorTaxAmountIsTooLarge()
  708. {
  709. $result = Braintree\Transaction::sale([
  710. 'amount' => '35.05',
  711. 'creditCard' => [
  712. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  713. 'expirationDate' => '05/2009',
  714. ],
  715. 'lineItems' => [
  716. [
  717. 'quantity' => '1.0232',
  718. 'name' => 'Name #1',
  719. 'kind' => Braintree\TransactionLineItem::DEBIT,
  720. 'unitAmount' => '45.1232',
  721. 'unitOfMeasure' => 'gallon',
  722. 'discountAmount' => '1.02',
  723. 'taxAmount' => '2147483648',
  724. 'totalAmount' => '45.15',
  725. 'productCode' => '23434',
  726. 'commodityCode' => '9SAASSD8724',
  727. ],
  728. ],
  729. ]);
  730. $this->assertFalse($result->success);
  731. $this->assertEquals(
  732. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_TAX_AMOUNT_IS_TOO_LARGE,
  733. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index0')->onAttribute('taxAmount')[0]->code
  734. );
  735. }
  736. public function testSale_withLineItemsValidationErrorTaxAmountCannotBeNegative()
  737. {
  738. $result = Braintree\Transaction::sale([
  739. 'amount' => '35.05',
  740. 'creditCard' => [
  741. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  742. 'expirationDate' => '05/2009',
  743. ],
  744. 'lineItems' => [
  745. [
  746. 'quantity' => '1.0232',
  747. 'name' => 'Name #1',
  748. 'kind' => Braintree\TransactionLineItem::DEBIT,
  749. 'unitAmount' => '45.1232',
  750. 'unitOfMeasure' => 'gallon',
  751. 'discountAmount' => '1.02',
  752. 'taxAmount' => '-2',
  753. 'totalAmount' => '45.15',
  754. 'productCode' => '23434',
  755. 'commodityCode' => '9SAASSD8724',
  756. ],
  757. ],
  758. ]);
  759. $this->assertFalse($result->success);
  760. $this->assertEquals(
  761. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_TAX_AMOUNT_CANNOT_BE_NEGATIVE,
  762. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index0')->onAttribute('taxAmount')[0]->code
  763. );
  764. }
  765. public function testSale_withLineItemsValidationErrorKindIsRequired()
  766. {
  767. $result = Braintree\Transaction::sale([
  768. 'amount' => '35.05',
  769. 'creditCard' => [
  770. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  771. 'expirationDate' => '05/2009',
  772. ],
  773. 'lineItems' => [
  774. [
  775. 'quantity' => '1.0232',
  776. 'name' => 'Name #1',
  777. 'kind' => Braintree\TransactionLineItem::DEBIT,
  778. 'unitAmount' => '45.1232',
  779. 'unitOfMeasure' => 'gallon',
  780. 'discountAmount' => '1.02',
  781. 'taxAmount' => '4.50',
  782. 'totalAmount' => '45.15',
  783. 'productCode' => '23434',
  784. 'commodityCode' => '9SAASSD8724',
  785. ],
  786. [
  787. 'quantity' => '1.0232',
  788. 'name' => 'Name #2',
  789. 'unitAmount' => '45.1232',
  790. 'unitOfMeasure' => 'gallon',
  791. 'discountAmount' => '1.02',
  792. 'taxAmount' => '4.50',
  793. 'totalAmount' => '45.15',
  794. 'productCode' => '23434',
  795. 'commodityCode' => '9SAASSD8724',
  796. ]
  797. ]
  798. ]);
  799. $this->assertFalse($result->success);
  800. $this->assertEquals(
  801. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_KIND_IS_REQUIRED,
  802. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('kind')[0]->code
  803. );
  804. }
  805. public function testSale_withLineItemsValidationErrorNameIsRequired()
  806. {
  807. $result = Braintree\Transaction::sale([
  808. 'amount' => '35.05',
  809. 'creditCard' => [
  810. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  811. 'expirationDate' => '05/2009',
  812. ],
  813. 'lineItems' => [
  814. [
  815. 'quantity' => '1.0232',
  816. 'name' => 'Name #1',
  817. 'kind' => Braintree\TransactionLineItem::DEBIT,
  818. 'unitAmount' => '45.1232',
  819. 'unitOfMeasure' => 'gallon',
  820. 'discountAmount' => '1.02',
  821. 'taxAmount' => '4.50',
  822. 'totalAmount' => '45.15',
  823. 'productCode' => '23434',
  824. 'commodityCode' => '9SAASSD8724',
  825. ],
  826. [
  827. 'quantity' => '1.0232',
  828. 'kind' => Braintree\TransactionLineItem::DEBIT,
  829. 'unitAmount' => '45.1232',
  830. 'unitOfMeasure' => 'gallon',
  831. 'discountAmount' => '1.02',
  832. 'taxAmount' => '4.50',
  833. 'totalAmount' => '45.15',
  834. 'productCode' => '23434',
  835. 'commodityCode' => '9SAASSD8724',
  836. ]
  837. ]
  838. ]);
  839. $this->assertFalse($result->success);
  840. $this->assertEquals(
  841. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_NAME_IS_REQUIRED,
  842. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('name')[0]->code
  843. );
  844. }
  845. public function testSale_withLineItemsValidationErrorNameIsTooLong()
  846. {
  847. $result = Braintree\Transaction::sale([
  848. 'amount' => '35.05',
  849. 'creditCard' => [
  850. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  851. 'expirationDate' => '05/2009',
  852. ],
  853. 'lineItems' => [
  854. [
  855. 'quantity' => '1.0232',
  856. 'name' => 'Name #1',
  857. 'kind' => Braintree\TransactionLineItem::DEBIT,
  858. 'unitAmount' => '45.1232',
  859. 'unitOfMeasure' => 'gallon',
  860. 'discountAmount' => '1.02',
  861. 'taxAmount' => '4.50',
  862. 'totalAmount' => '45.15',
  863. 'productCode' => '23434',
  864. 'commodityCode' => '9SAASSD8724',
  865. ],
  866. [
  867. 'quantity' => '1.0232',
  868. 'name' => '123456789012345678901234567890123456',
  869. 'kind' => Braintree\TransactionLineItem::DEBIT,
  870. 'unitAmount' => '45.1232',
  871. 'unitOfMeasure' => 'gallon',
  872. 'discountAmount' => '1.02',
  873. 'taxAmount' => '4.50',
  874. 'totalAmount' => '45.15',
  875. 'productCode' => '23434',
  876. 'commodityCode' => '9SAASSD8724',
  877. ]
  878. ]
  879. ]);
  880. $this->assertFalse($result->success);
  881. $this->assertEquals(
  882. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_NAME_IS_TOO_LONG,
  883. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('name')[0]->code
  884. );
  885. }
  886. public function testSale_withLineItemsValidationErrorProductCodeIsTooLong()
  887. {
  888. $result = Braintree\Transaction::sale([
  889. 'amount' => '35.05',
  890. 'creditCard' => [
  891. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  892. 'expirationDate' => '05/2009',
  893. ],
  894. 'lineItems' => [
  895. [
  896. 'quantity' => '1.0232',
  897. 'name' => 'Name #1',
  898. 'kind' => Braintree\TransactionLineItem::DEBIT,
  899. 'unitAmount' => '45.1232',
  900. 'unitOfMeasure' => 'gallon',
  901. 'discountAmount' => '1.02',
  902. 'taxAmount' => '4.50',
  903. 'totalAmount' => '45.15',
  904. 'productCode' => '23434',
  905. 'commodityCode' => '9SAASSD8724',
  906. ],
  907. [
  908. 'quantity' => '1.0232',
  909. 'name' => 'Name #2',
  910. 'kind' => Braintree\TransactionLineItem::CREDIT,
  911. 'unitAmount' => '45.1232',
  912. 'unitOfMeasure' => 'gallon',
  913. 'discountAmount' => '1.02',
  914. 'taxAmount' => '4.50',
  915. 'totalAmount' => '45.15',
  916. 'productCode' => '123456789012345678901234567890123456',
  917. 'commodityCode' => '9SAASSD8724',
  918. ]
  919. ]
  920. ]);
  921. $this->assertFalse($result->success);
  922. $this->assertEquals(
  923. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_PRODUCT_CODE_IS_TOO_LONG,
  924. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('productCode')[0]->code
  925. );
  926. }
  927. public function testSale_withLineItemsValidationErrorQuantityIsRequired()
  928. {
  929. $result = Braintree\Transaction::sale([
  930. 'amount' => '35.05',
  931. 'creditCard' => [
  932. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  933. 'expirationDate' => '05/2009',
  934. ],
  935. 'lineItems' => [
  936. [
  937. 'quantity' => '1.0232',
  938. 'name' => 'Name #1',
  939. 'kind' => Braintree\TransactionLineItem::DEBIT,
  940. 'unitAmount' => '45.1232',
  941. 'unitOfMeasure' => 'gallon',
  942. 'discountAmount' => '1.02',
  943. 'taxAmount' => '4.50',
  944. 'totalAmount' => '45.15',
  945. 'productCode' => '23434',
  946. 'commodityCode' => '9SAASSD8724',
  947. ],
  948. [
  949. 'name' => 'Name #2',
  950. 'kind' => Braintree\TransactionLineItem::CREDIT,
  951. 'unitAmount' => '45.1232',
  952. 'unitOfMeasure' => 'gallon',
  953. 'discountAmount' => '1.02',
  954. 'taxAmount' => '4.50',
  955. 'totalAmount' => '45.15',
  956. 'productCode' => '23434',
  957. 'commodityCode' => '9SAASSD8724',
  958. ]
  959. ]
  960. ]);
  961. $this->assertFalse($result->success);
  962. $this->assertEquals(
  963. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_QUANTITY_IS_REQUIRED,
  964. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('quantity')[0]->code
  965. );
  966. }
  967. public function testSale_withLineItemsValidationErrorQuantityIsTooLarge()
  968. {
  969. $result = Braintree\Transaction::sale([
  970. 'amount' => '35.05',
  971. 'creditCard' => [
  972. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  973. 'expirationDate' => '05/2009',
  974. ],
  975. 'lineItems' => [
  976. [
  977. 'quantity' => '1.0232',
  978. 'name' => 'Name #1',
  979. 'kind' => Braintree\TransactionLineItem::DEBIT,
  980. 'unitAmount' => '45.1232',
  981. 'unitOfMeasure' => 'gallon',
  982. 'discountAmount' => '1.02',
  983. 'taxAmount' => '4.50',
  984. 'totalAmount' => '45.15',
  985. 'productCode' => '23434',
  986. 'commodityCode' => '9SAASSD8724',
  987. ],
  988. [
  989. 'quantity' => '2147483648',
  990. 'name' => 'Name #2',
  991. 'kind' => Braintree\TransactionLineItem::CREDIT,
  992. 'unitAmount' => '45.1232',
  993. 'unitOfMeasure' => 'gallon',
  994. 'discountAmount' => '1.02',
  995. 'taxAmount' => '4.50',
  996. 'totalAmount' => '45.15',
  997. 'productCode' => '23434',
  998. 'commodityCode' => '9SAASSD8724',
  999. ]
  1000. ]
  1001. ]);
  1002. $this->assertFalse($result->success);
  1003. $this->assertEquals(
  1004. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_QUANTITY_IS_TOO_LARGE,
  1005. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('quantity')[0]->code
  1006. );
  1007. }
  1008. public function testSale_withLineItemsValidationErrorTotalAmountIsRequired()
  1009. {
  1010. $result = Braintree\Transaction::sale([
  1011. 'amount' => '35.05',
  1012. 'creditCard' => [
  1013. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  1014. 'expirationDate' => '05/2009',
  1015. ],
  1016. 'lineItems' => [
  1017. [
  1018. 'quantity' => '1.0232',
  1019. 'name' => 'Name #1',
  1020. 'kind' => Braintree\TransactionLineItem::DEBIT,
  1021. 'unitAmount' => '45.1232',
  1022. 'unitOfMeasure' => 'gallon',
  1023. 'discountAmount' => '1.02',
  1024. 'taxAmount' => '4.50',
  1025. 'totalAmount' => '45.15',
  1026. 'productCode' => '23434',
  1027. 'commodityCode' => '9SAASSD8724',
  1028. ],
  1029. [
  1030. 'quantity' => '1.0232',
  1031. 'name' => 'Name #2',
  1032. 'kind' => Braintree\TransactionLineItem::CREDIT,
  1033. 'unitAmount' => '45.1232',
  1034. 'unitOfMeasure' => 'gallon',
  1035. 'discountAmount' => '1.02',
  1036. 'taxAmount' => '4.50',
  1037. 'productCode' => '23434',
  1038. 'commodityCode' => '9SAASSD8724',
  1039. ]
  1040. ]
  1041. ]);
  1042. $this->assertFalse($result->success);
  1043. $this->assertEquals(
  1044. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_TOTAL_AMOUNT_IS_REQUIRED,
  1045. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('totalAmount')[0]->code
  1046. );
  1047. }
  1048. public function testSale_withLineItemsValidationErrorTotalAmountIsTooLarge()
  1049. {
  1050. $result = Braintree\Transaction::sale([
  1051. 'amount' => '35.05',
  1052. 'creditCard' => [
  1053. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  1054. 'expirationDate' => '05/2009',
  1055. ],
  1056. 'lineItems' => [
  1057. [
  1058. 'quantity' => '1.0232',
  1059. 'name' => 'Name #1',
  1060. 'kind' => Braintree\TransactionLineItem::DEBIT,
  1061. 'unitAmount' => '45.1232',
  1062. 'unitOfMeasure' => 'gallon',
  1063. 'discountAmount' => '1.02',
  1064. 'taxAmount' => '4.50',
  1065. 'totalAmount' => '45.15',
  1066. 'productCode' => '23434',
  1067. 'commodityCode' => '9SAASSD8724',
  1068. ],
  1069. [
  1070. 'quantity' => '1.0232',
  1071. 'name' => 'Name #2',
  1072. 'kind' => Braintree\TransactionLineItem::CREDIT,
  1073. 'unitAmount' => '45.1232',
  1074. 'unitOfMeasure' => 'gallon',
  1075. 'discountAmount' => '1.02',
  1076. 'taxAmount' => '4.50',
  1077. 'totalAmount' => '2147483648',
  1078. 'productCode' => '23434',
  1079. 'commodityCode' => '9SAASSD8724',
  1080. ]
  1081. ]
  1082. ]);
  1083. $this->assertFalse($result->success);
  1084. $this->assertEquals(
  1085. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_TOTAL_AMOUNT_IS_TOO_LARGE,
  1086. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('totalAmount')[0]->code
  1087. );
  1088. }
  1089. public function testSale_withLineItemsValidationErrorTotalAmountMustBeGreaterThanZero()
  1090. {
  1091. $result = Braintree\Transaction::sale([
  1092. 'amount' => '35.05',
  1093. 'creditCard' => [
  1094. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  1095. 'expirationDate' => '05/2009',
  1096. ],
  1097. 'lineItems' => [
  1098. [
  1099. 'quantity' => '1.0232',
  1100. 'name' => 'Name #1',
  1101. 'kind' => Braintree\TransactionLineItem::DEBIT,
  1102. 'unitAmount' => '45.1232',
  1103. 'unitOfMeasure' => 'gallon',
  1104. 'discountAmount' => '1.02',
  1105. 'taxAmount' => '4.50',
  1106. 'totalAmount' => '45.15',
  1107. 'productCode' => '23434',
  1108. 'commodityCode' => '9SAASSD8724',
  1109. ],
  1110. [
  1111. 'quantity' => '1.0232',
  1112. 'name' => 'Name #2',
  1113. 'kind' => Braintree\TransactionLineItem::CREDIT,
  1114. 'unitAmount' => '45.1232',
  1115. 'unitOfMeasure' => 'gallon',
  1116. 'discountAmount' => '1.02',
  1117. 'taxAmount' => '4.50',
  1118. 'totalAmount' => '-2',
  1119. 'productCode' => '23434',
  1120. 'commodityCode' => '9SAASSD8724',
  1121. ]
  1122. ]
  1123. ]);
  1124. $this->assertFalse($result->success);
  1125. $this->assertEquals(
  1126. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_TOTAL_AMOUNT_MUST_BE_GREATER_THAN_ZERO,
  1127. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('totalAmount')[0]->code
  1128. );
  1129. }
  1130. public function testSale_withLineItemsValidationErrorUnitAmountIsRequired()
  1131. {
  1132. $result = Braintree\Transaction::sale([
  1133. 'amount' => '35.05',
  1134. 'creditCard' => [
  1135. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  1136. 'expirationDate' => '05/2009',
  1137. ],
  1138. 'lineItems' => [
  1139. [
  1140. 'quantity' => '1.0232',
  1141. 'name' => 'Name #1',
  1142. 'kind' => Braintree\TransactionLineItem::DEBIT,
  1143. 'unitAmount' => '45.1232',
  1144. 'unitOfMeasure' => 'gallon',
  1145. 'discountAmount' => '1.02',
  1146. 'taxAmount' => '4.50',
  1147. 'totalAmount' => '45.15',
  1148. 'productCode' => '23434',
  1149. 'commodityCode' => '9SAASSD8724',
  1150. ],
  1151. [
  1152. 'quantity' => '1.0232',
  1153. 'name' => 'Name #2',
  1154. 'kind' => Braintree\TransactionLineItem::CREDIT,
  1155. 'unitOfMeasure' => 'gallon',
  1156. 'discountAmount' => '1.02',
  1157. 'taxAmount' => '4.50',
  1158. 'totalAmount' => '45.15',
  1159. 'productCode' => '23434',
  1160. 'commodityCode' => '9SAASSD8724',
  1161. ]
  1162. ]
  1163. ]);
  1164. $this->assertFalse($result->success);
  1165. $this->assertEquals(
  1166. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_UNIT_AMOUNT_IS_REQUIRED,
  1167. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('unitAmount')[0]->code
  1168. );
  1169. }
  1170. public function testSale_withLineItemsValidationErrorUnitAmountIsTooLarge()
  1171. {
  1172. $result = Braintree\Transaction::sale([
  1173. 'amount' => '35.05',
  1174. 'creditCard' => [
  1175. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  1176. 'expirationDate' => '05/2009',
  1177. ],
  1178. 'lineItems' => [
  1179. [
  1180. 'quantity' => '1.0232',
  1181. 'name' => 'Name #1',
  1182. 'kind' => Braintree\TransactionLineItem::DEBIT,
  1183. 'unitAmount' => '45.1232',
  1184. 'unitOfMeasure' => 'gallon',
  1185. 'discountAmount' => '1.02',
  1186. 'taxAmount' => '4.50',
  1187. 'totalAmount' => '45.15',
  1188. 'productCode' => '23434',
  1189. 'commodityCode' => '9SAASSD8724',
  1190. ],
  1191. [
  1192. 'quantity' => '1.0232',
  1193. 'name' => 'Name #2',
  1194. 'kind' => Braintree\TransactionLineItem::CREDIT,
  1195. 'unitAmount' => '2147483648',
  1196. 'unitOfMeasure' => 'gallon',
  1197. 'discountAmount' => '1.02',
  1198. 'taxAmount' => '4.50',
  1199. 'totalAmount' => '45.15',
  1200. 'productCode' => '23434',
  1201. 'commodityCode' => '9SAASSD8724',
  1202. ]
  1203. ]
  1204. ]);
  1205. $this->assertFalse($result->success);
  1206. $this->assertEquals(
  1207. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_UNIT_AMOUNT_IS_TOO_LARGE,
  1208. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('unitAmount')[0]->code
  1209. );
  1210. }
  1211. public function testSale_withLineItemsValidationErrorUnitAmountMustBeGreaterThanZero()
  1212. {
  1213. $result = Braintree\Transaction::sale([
  1214. 'amount' => '35.05',
  1215. 'creditCard' => [
  1216. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  1217. 'expirationDate' => '05/2009',
  1218. ],
  1219. 'lineItems' => [
  1220. [
  1221. 'quantity' => '1.0232',
  1222. 'name' => 'Name #1',
  1223. 'kind' => Braintree\Transaction\LineItem::DEBIT,
  1224. 'unitAmount' => '45.1232',
  1225. 'unitOfMeasure' => 'gallon',
  1226. 'discountAmount' => '1.02',
  1227. 'taxAmount' => '4.50',
  1228. 'totalAmount' => '45.15',
  1229. 'productCode' => '23434',
  1230. 'commodityCode' => '9SAASSD8724',
  1231. ],
  1232. [
  1233. 'quantity' => '1.0232',
  1234. 'name' => 'Name #2',
  1235. 'kind' => Braintree\Transaction\LineItem::CREDIT,
  1236. 'unitAmount' => '-2',
  1237. 'unitOfMeasure' => 'gallon',
  1238. 'discountAmount' => '1.02',
  1239. 'taxAmount' => '4.50',
  1240. 'totalAmount' => '45.15',
  1241. 'productCode' => '23434',
  1242. 'commodityCode' => '9SAASSD8724',
  1243. ]
  1244. ]
  1245. ]);
  1246. $this->assertFalse($result->success);
  1247. $this->assertEquals(
  1248. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_UNIT_AMOUNT_MUST_BE_GREATER_THAN_ZERO,
  1249. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('unitAmount')[0]->code
  1250. );
  1251. }
  1252. public function testSale_withLineItemsValidationErrorUnitOfMeasureIsTooLong()
  1253. {
  1254. $result = Braintree\Transaction::sale([
  1255. 'amount' => '35.05',
  1256. 'creditCard' => [
  1257. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  1258. 'expirationDate' => '05/2009',
  1259. ],
  1260. 'lineItems' => [
  1261. [
  1262. 'quantity' => '1.0232',
  1263. 'name' => 'Name #1',
  1264. 'kind' => Braintree\Transaction\LineItem::DEBIT,
  1265. 'unitAmount' => '45.1232',
  1266. 'unitOfMeasure' => 'gallon',
  1267. 'discountAmount' => '1.02',
  1268. 'taxAmount' => '4.50',
  1269. 'totalAmount' => '45.15',
  1270. 'productCode' => '23434',
  1271. 'commodityCode' => '9SAASSD8724',
  1272. ],
  1273. [
  1274. 'quantity' => '1.0232',
  1275. 'name' => 'Name #2',
  1276. 'kind' => Braintree\Transaction\LineItem::CREDIT,
  1277. 'unitAmount' => '45.1232',
  1278. 'unitOfMeasure' => '1234567890123',
  1279. 'discountAmount' => '1.02',
  1280. 'taxAmount' => '4.50',
  1281. 'totalAmount' => '45.15',
  1282. 'productCode' => '23434',
  1283. 'commodityCode' => '9SAASSD8724',
  1284. ]
  1285. ]
  1286. ]);
  1287. $this->assertFalse($result->success);
  1288. $this->assertEquals(
  1289. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_UNIT_OF_MEASURE_IS_TOO_LONG,
  1290. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('unitOfMeasure')[0]->code
  1291. );
  1292. }
  1293. public function testSale_withLineItemsValidationErrorUnitTaxAmountFormatIsInvalid()
  1294. {
  1295. $result = Braintree\Transaction::sale([
  1296. 'amount' => '35.05',
  1297. 'creditCard' => [
  1298. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  1299. 'expirationDate' => '05/2009',
  1300. ],
  1301. 'lineItems' => [
  1302. [
  1303. 'quantity' => '1.2322',
  1304. 'name' => 'Name #1',
  1305. 'kind' => Braintree\Transaction\LineItem::DEBIT,
  1306. 'unitAmount' => '45.1232',
  1307. 'unitOfMeasure' => 'gallon',
  1308. 'discountAmount' => '1.02',
  1309. 'taxAmount' => '4.50',
  1310. 'totalAmount' => '45.15',
  1311. 'productCode' => '23434',
  1312. 'commodityCode' => '9SAASSD8724',
  1313. ],
  1314. [
  1315. 'quantity' => '1.2322',
  1316. 'name' => 'Name #2',
  1317. 'kind' => Braintree\Transaction\LineItem::CREDIT,
  1318. 'unitAmount' => '45.0122',
  1319. 'unitTaxAmount' => '2.012',
  1320. 'unitOfMeasure' => 'gallon',
  1321. 'discountAmount' => '1.02',
  1322. 'taxAmount' => '4.50',
  1323. 'totalAmount' => '45.15',
  1324. 'productCode' => '23434',
  1325. 'commodityCode' => '9SAASSD8724',
  1326. ]
  1327. ]
  1328. ]);
  1329. $this->assertFalse($result->success);
  1330. $this->assertEquals(
  1331. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_UNIT_TAX_AMOUNT_FORMAT_IS_INVALID,
  1332. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('unitTaxAmount')[0]->code
  1333. );
  1334. }
  1335. public function testSale_withLineItemsValidationErrorUnitTaxAmountIsTooLarge()
  1336. {
  1337. $result = Braintree\Transaction::sale([
  1338. 'amount' => '35.05',
  1339. 'creditCard' => [
  1340. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  1341. 'expirationDate' => '05/2009',
  1342. ],
  1343. 'lineItems' => [
  1344. [
  1345. 'quantity' => '1.2322',
  1346. 'name' => 'Name #1',
  1347. 'kind' => Braintree\Transaction\LineItem::DEBIT,
  1348. 'unitAmount' => '45.1232',
  1349. 'unitTaxAmount' => '1.23',
  1350. 'unitOfMeasure' => 'gallon',
  1351. 'discountAmount' => '1.02',
  1352. 'taxAmount' => '4.50',
  1353. 'totalAmount' => '45.15',
  1354. 'productCode' => '23434',
  1355. 'commodityCode' => '9SAASSD8724',
  1356. ],
  1357. [
  1358. 'quantity' => '1.2322',
  1359. 'name' => 'Name #2',
  1360. 'kind' => Braintree\Transaction\LineItem::CREDIT,
  1361. 'unitAmount' => '45.0122',
  1362. 'unitTaxAmount' => '2147483648',
  1363. 'unitOfMeasure' => 'gallon',
  1364. 'discountAmount' => '1.02',
  1365. 'taxAmount' => '4.50',
  1366. 'totalAmount' => '45.15',
  1367. 'productCode' => '23434',
  1368. 'commodityCode' => '9SAASSD8724',
  1369. ]
  1370. ]
  1371. ]);
  1372. $this->assertFalse($result->success);
  1373. $this->assertEquals(
  1374. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_UNIT_TAX_AMOUNT_IS_TOO_LARGE,
  1375. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('unitTaxAmount')[0]->code
  1376. );
  1377. }
  1378. public function testSale_withLineItemsValidationErrorUnitTaxAmountCannotBeNegative()
  1379. {
  1380. $result = Braintree\Transaction::sale([
  1381. 'amount' => '35.05',
  1382. 'creditCard' => [
  1383. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  1384. 'expirationDate' => '05/2009',
  1385. ],
  1386. 'lineItems' => [
  1387. [
  1388. 'quantity' => '1.2322',
  1389. 'name' => 'Name #1',
  1390. 'kind' => Braintree\Transaction\LineItem::DEBIT,
  1391. 'unitAmount' => '45.1232',
  1392. 'unitOfMeasure' => 'gallon',
  1393. 'discountAmount' => '1.02',
  1394. 'taxAmount' => '4.50',
  1395. 'totalAmount' => '45.15',
  1396. 'productCode' => '23434',
  1397. 'commodityCode' => '9SAASSD8724',
  1398. ],
  1399. [
  1400. 'quantity' => '1.2322',
  1401. 'name' => 'Name #2',
  1402. 'kind' => Braintree\Transaction\LineItem::CREDIT,
  1403. 'unitAmount' => '45.0122',
  1404. 'unitTaxAmount' => '-1.23',
  1405. 'unitOfMeasure' => 'gallon',
  1406. 'discountAmount' => '1.02',
  1407. 'taxAmount' => '4.50',
  1408. 'totalAmount' => '45.15',
  1409. 'productCode' => '23434',
  1410. 'commodityCode' => '9SAASSD8724',
  1411. ]
  1412. ]
  1413. ]);
  1414. $this->assertFalse($result->success);
  1415. $this->assertEquals(
  1416. Braintree\Error\Codes::TRANSACTION_LINE_ITEM_UNIT_TAX_AMOUNT_CANNOT_BE_NEGATIVE,
  1417. $result->errors->forKey('transaction')->forKey('lineItems')->forKey('index1')->onAttribute('unitTaxAmount')[0]->code
  1418. );
  1419. }
  1420. public function testSale_withLineItemsValidationErrorTooManyLineItems()
  1421. {
  1422. $transactionParams = [
  1423. 'amount' => '35.05',
  1424. 'creditCard' => [
  1425. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  1426. 'expirationDate' => '05/2009',
  1427. ],
  1428. 'lineItems' => [],
  1429. ];
  1430. for ($i = 0; $i < 250; $i++) {
  1431. array_push($transactionParams['lineItems'], [
  1432. 'quantity' => '2.02',
  1433. 'name' => 'Line item #' . $i,
  1434. 'kind' => Braintree\Transaction\LineItem::CREDIT,
  1435. 'unitAmount' => '5',
  1436. 'unitOfMeasure' => 'gallon',
  1437. 'totalAmount' => '10.1',
  1438. ]);
  1439. }
  1440. $result = Braintree\Transaction::sale($transactionParams);
  1441. $this->assertFalse($result->success);
  1442. $this->assertEquals(
  1443. Braintree\Error\Codes::TRANSACTION_TOO_MANY_LINE_ITEMS,
  1444. $result->errors->forKey('transaction')->onAttribute('lineItems')[0]->code
  1445. );
  1446. }
  1447. public function testCreateTransactionUsingFakeApplePayNonce()
  1448. {
  1449. $result = Braintree\Transaction::sale([
  1450. 'amount' => '47.00',
  1451. 'paymentMethodNonce' => Braintree\Test\Nonces::$applePayAmEx
  1452. ]);
  1453. $this->assertTrue($result->success);
  1454. $transaction = $result->transaction;
  1455. $this->assertEquals('47.00', $transaction->amount);
  1456. $applePayDetails = $transaction->applePayCardDetails;
  1457. $this->assertSame(Braintree\ApplePayCard::AMEX, $applePayDetails->cardType);
  1458. $this->assertContains("AmEx ", $applePayDetails->sourceDescription);
  1459. $this->assertContains("AmEx ", $applePayDetails->paymentInstrumentName);
  1460. $this->assertTrue(intval($applePayDetails->expirationMonth) > 0);
  1461. $this->assertTrue(intval($applePayDetails->expirationYear) > 0);
  1462. $this->assertNotNull($applePayDetails->cardholderName);
  1463. }
  1464. public function testCreateTransactionUsingRawApplePayParams()
  1465. {
  1466. $result = Braintree\Transaction::sale([
  1467. 'amount' => '1.02',
  1468. 'applePayCard' => [
  1469. 'number' => "370295001292109",
  1470. 'cardholderName' => "JANE SMITH",
  1471. 'cryptogram' => "AAAAAAAA/COBt84dnIEcwAA3gAAGhgEDoLABAAhAgAABAAAALnNCLw==",
  1472. 'expirationMonth' => "10",
  1473. 'expirationYear' => "17",
  1474. 'eciIndicator' => "07"
  1475. ]
  1476. ]);
  1477. $this->assertTrue($result->success);
  1478. }
  1479. public function testCreateTransactionUsingRawApplePayParamsInSnakeCaseForBackwardsCompatibility()
  1480. {
  1481. $result = Braintree\Transaction::sale([
  1482. 'amount' => '1.02',
  1483. 'apple_pay_card' => [
  1484. 'number' => "370295001292109",
  1485. 'cardholder_name' => "JANE SMITH",
  1486. 'cryptogram' => "AAAAAAAA/COBt84dnIEcwAA3gAAGhgEDoLABAAhAgAABAAAALnNCLw==",
  1487. 'expiration_month' => "10",
  1488. 'expiration_year' => "17",
  1489. 'eci_indicator' => "07"
  1490. ]
  1491. ]);
  1492. $this->assertTrue($result->success);
  1493. }
  1494. public function testCreateTransactionUsingFakeAndroidPayProxyCardNonce()
  1495. {
  1496. $result = Braintree\Transaction::sale([
  1497. 'amount' => '47.00',
  1498. 'paymentMethodNonce' => Braintree\Test\Nonces::$androidPayDiscover
  1499. ]);
  1500. $this->assertTrue($result->success);
  1501. $transaction = $result->transaction;
  1502. $this->assertEquals('47.00', $transaction->amount);
  1503. $androidPayCardDetails = $transaction->androidPayCardDetails;
  1504. $this->assertSame(Braintree\CreditCard::DISCOVER, $androidPayCardDetails->cardType);
  1505. $this->assertSame("1117", $androidPayCardDetails->last4);
  1506. $this->assertNull($androidPayCardDetails->token);
  1507. $this->assertSame(Braintree\CreditCard::DISCOVER, $androidPayCardDetails->virtualCardType);
  1508. $this->assertSame("1117", $androidPayCardDetails->virtualCardLast4);
  1509. $this->assertSame(Braintree\CreditCard::DISCOVER, $androidPayCardDetails->sourceCardType);
  1510. $this->assertSame("1111", $androidPayCardDetails->sourceCardLast4);
  1511. $this->assertSame("Discover 1111", $androidPayCardDetails->sourceDescription);
  1512. $this->assertContains('android_pay', $androidPayCardDetails->imageUrl);
  1513. $this->assertTrue(intval($androidPayCardDetails->expirationMonth) > 0);
  1514. $this->assertTrue(intval($androidPayCardDetails->expirationYear) > 0);
  1515. }
  1516. public function testCreateTransactionUsingFakeAndroidPayNetworkTokenNonce()
  1517. {
  1518. $result = Braintree\Transaction::sale([
  1519. 'amount' => '47.00',
  1520. 'paymentMethodNonce' => Braintree\Test\Nonces::$androidPayMasterCard
  1521. ]);
  1522. $this->assertTrue($result->success);
  1523. $transaction = $result->transaction;
  1524. $this->assertEquals('47.00', $transaction->amount);
  1525. $androidPayCardDetails = $transaction->androidPayCardDetails;
  1526. $this->assertSame(Braintree\CreditCard::MASTER_CARD, $androidPayCardDetails->cardType);
  1527. $this->assertSame("4444", $androidPayCardDetails->last4);
  1528. $this->assertNull($androidPayCardDetails->token);
  1529. $this->assertSame(Braintree\CreditCard::MASTER_CARD, $androidPayCardDetails->virtualCardType);
  1530. $this->assertSame("4444", $androidPayCardDetails->virtualCardLast4);
  1531. $this->assertSame(Braintree\CreditCard::MASTER_CARD, $androidPayCardDetails->sourceCardType);
  1532. $this->assertSame("4444", $androidPayCardDetails->sourceCardLast4);
  1533. $this->assertSame("MasterCard 4444", $androidPayCardDetails->sourceDescription);
  1534. $this->assertContains('android_pay', $androidPayCardDetails->imageUrl);
  1535. $this->assertTrue(intval($androidPayCardDetails->expirationMonth) > 0);
  1536. $this->assertTrue(intval($androidPayCardDetails->expirationYear) > 0);
  1537. }
  1538. public function testCreateTransactionUsingFakeAmexExpressCheckoutNonce()
  1539. {
  1540. $result = Braintree\Transaction::sale([
  1541. 'amount' => '47.00',
  1542. 'merchantAccountId' => Test\Helper::fakeAmexDirectMerchantAccountId(),
  1543. 'paymentMethodNonce' => Braintree\Test\Nonces::$amexExpressCheckout
  1544. ]);
  1545. $this->assertTrue($result->success);
  1546. $transaction = $result->transaction;
  1547. $this->assertEquals('47.00', $transaction->amount);
  1548. $amexExpressCheckoutCardDetails = $transaction->amexExpressCheckoutCardDetails;
  1549. $this->assertSame(Braintree\CreditCard::AMEX, $amexExpressCheckoutCardDetails->cardType);
  1550. $this->assertSame("341111", $amexExpressCheckoutCardDetails->bin);
  1551. $this->assertSame("12/21", $amexExpressCheckoutCardDetails->cardMemberExpiryDate);
  1552. $this->assertSame("0005", $amexExpressCheckoutCardDetails->cardMemberNumber);
  1553. $this->assertNull($amexExpressCheckoutCardDetails->token);
  1554. $this->assertNotNull($amexExpressCheckoutCardDetails->sourceDescription);
  1555. $this->assertContains(".png", $amexExpressCheckoutCardDetails->imageUrl);
  1556. $this->assertTrue(intval($amexExpressCheckoutCardDetails->expirationMonth) > 0);
  1557. $this->assertTrue(intval($amexExpressCheckoutCardDetails->expirationYear) > 0);
  1558. }
  1559. public function testCreateTransactionUsingFakeVenmoAccountNonceAndProfileId()
  1560. {
  1561. $result = Braintree\Transaction::sale(array(
  1562. 'amount' => '47.00',
  1563. 'merchantAccountId' => Test\Helper::fakeVenmoAccountMerchantAccountId(),
  1564. 'paymentMethodNonce' => Braintree\Test\Nonces::$venmoAccount,
  1565. 'options' => [
  1566. 'venmo' => [
  1567. 'profileId' => "integration_venmo_merchant_public_id"
  1568. ]
  1569. ]
  1570. ));
  1571. $this->assertTrue($result->success);
  1572. }
  1573. public function testCreateTransactionUsingFakeVenmoAccountNonceAndProfileIdUsingSnakeCaseKeyforProfileId()
  1574. {
  1575. $result = Braintree\Transaction::sale(array(
  1576. 'amount' => '47.00',
  1577. 'merchantAccountId' => Test\Helper::fakeVenmoAccountMerchantAccountId(),
  1578. 'paymentMethodNonce' => Braintree\Test\Nonces::$venmoAccount,
  1579. 'options' => [
  1580. 'venmo' => [
  1581. 'profile_id' => "integration_venmo_merchant_public_id"
  1582. ]
  1583. ]
  1584. ));
  1585. $this->assertTrue($result->success);
  1586. }
  1587. public function testCreateTransactionUsingFakeVenmoAccountNonce()
  1588. {
  1589. $result = Braintree\Transaction::sale(array(
  1590. 'amount' => '47.00',
  1591. 'merchantAccountId' => Test\Helper::fakeVenmoAccountMerchantAccountId(),
  1592. 'paymentMethodNonce' => Braintree\Test\Nonces::$venmoAccount
  1593. ));
  1594. $this->assertTrue($result->success);
  1595. $transaction = $result->transaction;
  1596. $this->assertEquals('47.00', $transaction->amount);
  1597. $this->assertEquals(Braintree\PaymentInstrumentType::VENMO_ACCOUNT, $transaction->paymentInstrumentType);
  1598. $venmoAccountDetails = $transaction->venmoAccountDetails;
  1599. $this->assertNull($venmoAccountDetails->token);
  1600. $this->assertNotNull($venmoAccountDetails->sourceDescription);
  1601. $this->assertContains(".png", $venmoAccountDetails->imageUrl);
  1602. $this->assertSame("venmojoe", $venmoAccountDetails->username);
  1603. $this->assertSame("Venmo-Joe-1", $venmoAccountDetails->venmoUserId);
  1604. }
  1605. public function testCannotCreateTransactionUsingFakeCoinbaseNonce()
  1606. {
  1607. $result = Braintree\Transaction::sale([
  1608. 'amount' => '17.00',
  1609. 'paymentMethodNonce' => Braintree\Test\Nonces::$coinbase
  1610. ]);
  1611. $this->assertFalse($result->success);
  1612. $this->assertEquals(Braintree\Error\Codes::PAYMENT_METHOD_NO_LONGER_SUPPORTED, $result->errors->forKey('transaction')->onAttribute('base')[0]->code);
  1613. }
  1614. public function testCreateTransactionReturnsPaymentInstrumentType()
  1615. {
  1616. $http = new HttpClientApi(Braintree\Configuration::$global);
  1617. $nonce = $http->nonce_for_new_card([
  1618. "creditCard" => [
  1619. "number" => "4111111111111111",
  1620. "expirationMonth" => "11",
  1621. "expirationYear" => "2099"
  1622. ],
  1623. "share" => true
  1624. ]);
  1625. $result = Braintree\Transaction::sale([
  1626. 'amount' => '47.00',
  1627. 'paymentMethodNonce' => $nonce
  1628. ]);
  1629. $this->assertTrue($result->success);
  1630. $transaction = $result->transaction;
  1631. $this->assertEquals(Braintree\PaymentInstrumentType::CREDIT_CARD, $transaction->paymentInstrumentType);
  1632. }
  1633. public function testCloneTransactionAndSubmitForSettlement()
  1634. {
  1635. $result = Braintree\Transaction::sale([
  1636. 'amount' => '100.00',
  1637. 'creditCard' => [
  1638. 'number' => '5105105105105100',
  1639. 'expirationDate' => '05/2011',
  1640. ]
  1641. ]);
  1642. $this->assertTrue($result->success);
  1643. $transaction = $result->transaction;
  1644. $cloneResult = Braintree\Transaction::cloneTransaction($transaction->id, ['amount' => '123.45', 'options' => ['submitForSettlement' => true]]);
  1645. $cloneTransaction = $cloneResult->transaction;
  1646. $this->assertEquals('submitted_for_settlement', $cloneTransaction->status);
  1647. }
  1648. public function testCloneWithValidations()
  1649. {
  1650. $result = Braintree\Transaction::credit([
  1651. 'amount' => '100.00',
  1652. 'creditCard' => [
  1653. 'number' => '5105105105105100',
  1654. 'expirationDate' => '05/2011'
  1655. ]
  1656. ]);
  1657. $this->assertTrue($result->success);
  1658. $transaction = $result->transaction;
  1659. $cloneResult = Braintree\Transaction::cloneTransaction($transaction->id, ['amount' => '123.45']);
  1660. $this->assertFalse($cloneResult->success);
  1661. $baseErrors = $cloneResult->errors->forKey('transaction')->onAttribute('base');
  1662. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_CANNOT_CLONE_CREDIT, $baseErrors[0]->code);
  1663. }
  1664. public function testSale()
  1665. {
  1666. $result = Braintree\Transaction::sale([
  1667. 'amount' => '100.00',
  1668. 'creditCard' => [
  1669. 'cardholderName' => 'The Cardholder',
  1670. 'number' => '5105105105105100',
  1671. 'expirationDate' => '05/12'
  1672. ]
  1673. ]);
  1674. $this->assertTrue($result->success);
  1675. $transaction = $result->transaction;
  1676. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  1677. $this->assertEquals(Braintree\Transaction::SALE, $transaction->type);
  1678. $this->assertEquals('100.00', $transaction->amount);
  1679. $this->assertNotNull($transaction->processorAuthorizationCode);
  1680. $this->assertEquals('510510', $transaction->creditCardDetails->bin);
  1681. $this->assertEquals('5100', $transaction->creditCardDetails->last4);
  1682. $this->assertEquals('The Cardholder', $transaction->creditCardDetails->cardholderName);
  1683. }
  1684. public function testSaleWithAccessToken()
  1685. {
  1686. $credentials = Test\Braintree\OAuthTestHelper::createCredentials([
  1687. 'clientId' => 'client_id$development$integration_client_id',
  1688. 'clientSecret' => 'client_secret$development$integration_client_secret',
  1689. 'merchantId' => 'integration_merchant_id',
  1690. ]);
  1691. $gateway = new Braintree\Gateway([
  1692. 'accessToken' => $credentials->accessToken,
  1693. ]);
  1694. $result = $gateway->transaction()->sale([
  1695. 'amount' => '100.00',
  1696. 'creditCard' => [
  1697. 'cardholderName' => 'The Cardholder',
  1698. 'number' => '5105105105105100',
  1699. 'expirationDate' => '05/12'
  1700. ]
  1701. ]);
  1702. $this->assertTrue($result->success);
  1703. $transaction = $result->transaction;
  1704. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  1705. $this->assertEquals(Braintree\Transaction::SALE, $transaction->type);
  1706. $this->assertEquals('100.00', $transaction->amount);
  1707. $this->assertNotNull($transaction->processorAuthorizationCode);
  1708. $this->assertEquals('510510', $transaction->creditCardDetails->bin);
  1709. $this->assertEquals('5100', $transaction->creditCardDetails->last4);
  1710. $this->assertEquals('The Cardholder', $transaction->creditCardDetails->cardholderName);
  1711. }
  1712. public function testSaleWithRiskData()
  1713. {
  1714. $gateway = Test\Helper::advancedFraudIntegrationMerchantGateway();
  1715. $result = $gateway->transaction()->sale([
  1716. 'amount' => '100.00',
  1717. 'deviceSessionId' => 'abc123',
  1718. 'creditCard' => [
  1719. 'cardholderName' => 'The Cardholder',
  1720. 'number' => '5105105105105100',
  1721. 'expirationDate' => '05/12'
  1722. ]
  1723. ]);
  1724. $this->assertTrue($result->success);
  1725. $transaction = $result->transaction;
  1726. $this->assertNotNull($transaction->riskData);
  1727. $this->assertNotNull($transaction->riskData->decision);
  1728. $this->assertNotNull($transaction->riskData->id);
  1729. $this->assertNotNull($transaction->riskData->deviceDataCaptured);
  1730. }
  1731. public function testRecurring()
  1732. {
  1733. $result = Braintree\Transaction::sale([
  1734. 'amount' => '100.00',
  1735. 'recurring' => true,
  1736. 'creditCard' => [
  1737. 'cardholderName' => 'The Cardholder',
  1738. 'number' => '5105105105105100',
  1739. 'expirationDate' => '05/12'
  1740. ]
  1741. ]);
  1742. $this->assertTrue($result->success);
  1743. $transaction = $result->transaction;
  1744. $this->assertEquals(true, $transaction->recurring);
  1745. }
  1746. public function testTransactionSourceWithRecurringFirst()
  1747. {
  1748. $result = Braintree\Transaction::sale([
  1749. 'amount' => '100.00',
  1750. 'transactionSource' => 'recurring_first',
  1751. 'creditCard' => [
  1752. 'cardholderName' => 'The Cardholder',
  1753. 'number' => '5105105105105100',
  1754. 'expirationDate' => '05/12'
  1755. ]
  1756. ]);
  1757. $this->assertTrue($result->success);
  1758. $transaction = $result->transaction;
  1759. $this->assertEquals(true, $transaction->recurring);
  1760. }
  1761. public function testTransactionSourceWithRecurring()
  1762. {
  1763. $result = Braintree\Transaction::sale([
  1764. 'amount' => '100.00',
  1765. 'transactionSource' => 'recurring',
  1766. 'creditCard' => [
  1767. 'cardholderName' => 'The Cardholder',
  1768. 'number' => '5105105105105100',
  1769. 'expirationDate' => '05/12'
  1770. ]
  1771. ]);
  1772. $this->assertTrue($result->success);
  1773. $transaction = $result->transaction;
  1774. $this->assertEquals(true, $transaction->recurring);
  1775. }
  1776. public function testTransactionSourceWithMerchant()
  1777. {
  1778. $result = Braintree\Transaction::sale([
  1779. 'amount' => '100.00',
  1780. 'transactionSource' => 'merchant',
  1781. 'creditCard' => [
  1782. 'cardholderName' => 'The Cardholder',
  1783. 'number' => '5105105105105100',
  1784. 'expirationDate' => '05/12'
  1785. ]
  1786. ]);
  1787. $this->assertTrue($result->success);
  1788. $transaction = $result->transaction;
  1789. $this->assertEquals(false, $transaction->recurring);
  1790. }
  1791. public function testTransactionSourceWithMoto()
  1792. {
  1793. $result = Braintree\Transaction::sale([
  1794. 'amount' => '100.00',
  1795. 'transactionSource' => 'moto',
  1796. 'creditCard' => [
  1797. 'cardholderName' => 'The Cardholder',
  1798. 'number' => '5105105105105100',
  1799. 'expirationDate' => '05/12'
  1800. ]
  1801. ]);
  1802. $this->assertTrue($result->success);
  1803. $transaction = $result->transaction;
  1804. $this->assertEquals(False, $transaction->recurring);
  1805. }
  1806. public function testTransactionSourceInvalid()
  1807. {
  1808. $result = Braintree\Transaction::sale([
  1809. 'amount' => '100.00',
  1810. 'transactionSource' => 'invalid_value',
  1811. 'creditCard' => [
  1812. 'cardholderName' => 'The Cardholder',
  1813. 'number' => '5105105105105100',
  1814. 'expirationDate' => '05/12'
  1815. ]
  1816. ]);
  1817. $this->assertFalse($result->success);
  1818. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_TRANSACTION_SOURCE_IS_INVALID, $result->errors->forKey('transaction')->onAttribute('transactionSource')[0]->code);
  1819. }
  1820. public function testSale_withServiceFee()
  1821. {
  1822. $result = Braintree\Transaction::sale([
  1823. 'amount' => '10.00',
  1824. 'merchantAccountId' => Test\Helper::nonDefaultSubMerchantAccountId(),
  1825. 'creditCard' => [
  1826. 'number' => '5105105105105100',
  1827. 'expirationDate' => '05/12'
  1828. ],
  1829. 'serviceFeeAmount' => '1.00'
  1830. ]);
  1831. $this->assertTrue($result->success);
  1832. $transaction = $result->transaction;
  1833. $this->assertEquals('1.00', $transaction->serviceFeeAmount);
  1834. }
  1835. public function testSale_isInvalidIfTransactionMerchantAccountIsNotSub()
  1836. {
  1837. $result = Braintree\Transaction::sale([
  1838. 'amount' => '10.00',
  1839. 'merchantAccountId' => Test\Helper::nonDefaultMerchantAccountId(),
  1840. 'creditCard' => [
  1841. 'number' => '5105105105105100',
  1842. 'expirationDate' => '05/12'
  1843. ],
  1844. 'serviceFeeAmount' => '1.00'
  1845. ]);
  1846. $this->assertFalse($result->success);
  1847. $transaction = $result->transaction;
  1848. $serviceFeeErrors = $result->errors->forKey('transaction')->onAttribute('serviceFeeAmount');
  1849. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_SERVICE_FEE_AMOUNT_NOT_ALLOWED_ON_MASTER_MERCHANT_ACCOUNT, $serviceFeeErrors[0]->code);
  1850. }
  1851. public function testSale_isInvalidIfSubMerchantAccountHasNoServiceFee()
  1852. {
  1853. $result = Braintree\Transaction::sale([
  1854. 'amount' => '10.00',
  1855. 'merchantAccountId' => Test\Helper::nonDefaultSubMerchantAccountId(),
  1856. 'creditCard' => [
  1857. 'number' => '5105105105105100',
  1858. 'expirationDate' => '05/12'
  1859. ]
  1860. ]);
  1861. $this->assertFalse($result->success);
  1862. $transaction = $result->transaction;
  1863. $serviceFeeErrors = $result->errors->forKey('transaction')->onAttribute('merchantAccountId');
  1864. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_SUB_MERCHANT_ACCOUNT_REQUIRES_SERVICE_FEE_AMOUNT, $serviceFeeErrors[0]->code);
  1865. }
  1866. public function testSale_withVenmoSdkSession()
  1867. {
  1868. $result = Braintree\Transaction::sale([
  1869. 'amount' => '10.00',
  1870. 'creditCard' => [
  1871. 'number' => '5105105105105100',
  1872. 'expirationDate' => '05/12'
  1873. ],
  1874. 'options' => [
  1875. 'venmoSdkSession' => Braintree\Test\VenmoSdk::getTestSession()
  1876. ]
  1877. ]);
  1878. $this->assertEquals(true, $result->success);
  1879. $transaction = $result->transaction;
  1880. $this->assertEquals(false, $transaction->creditCardDetails->venmoSdk);
  1881. }
  1882. public function testSale_withVenmoSdkPaymentMethodCode()
  1883. {
  1884. $result = Braintree\Transaction::sale([
  1885. 'amount' => '10.00',
  1886. 'venmoSdkPaymentMethodCode' => Braintree\Test\VenmoSdk::$visaPaymentMethodCode
  1887. ]);
  1888. $this->assertTrue($result->success);
  1889. $transaction = $result->transaction;
  1890. $this->assertEquals("411111", $transaction->creditCardDetails->bin);
  1891. }
  1892. public function testSale_withLevel2Attributes()
  1893. {
  1894. $result = Braintree\Transaction::sale([
  1895. 'amount' => '100.00',
  1896. 'creditCard' => [
  1897. 'cardholderName' => 'The Cardholder',
  1898. 'expirationDate' => '05/2011',
  1899. 'number' => '5105105105105100'
  1900. ],
  1901. 'taxExempt' => true,
  1902. 'taxAmount' => '10.00',
  1903. 'purchaseOrderNumber' => '12345'
  1904. ]);
  1905. $this->assertTrue($result->success);
  1906. $transaction = $result->transaction;
  1907. $this->assertTrue($transaction->taxExempt);
  1908. $this->assertEquals('10.00', $transaction->taxAmount);
  1909. $this->assertEquals('12345', $transaction->purchaseOrderNumber);
  1910. }
  1911. public function testSale_withInvalidTaxAmountAttribute()
  1912. {
  1913. $result = Braintree\Transaction::sale([
  1914. 'amount' => '100.00',
  1915. 'creditCard' => [
  1916. 'cardholderName' => 'The Cardholder',
  1917. 'expirationDate' => '05/2011',
  1918. 'number' => '5105105105105100'
  1919. ],
  1920. 'taxAmount' => 'abc'
  1921. ]);
  1922. $this->assertFalse($result->success);
  1923. $taxAmountErrors = $result->errors->forKey('transaction')->onAttribute('taxAmount');
  1924. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_TAX_AMOUNT_FORMAT_IS_INVALID, $taxAmountErrors[0]->code);
  1925. }
  1926. public function testSale_withServiceFeeTooLarge()
  1927. {
  1928. $result = Braintree\Transaction::sale([
  1929. 'amount' => '10.00',
  1930. 'merchantAccountId' => Test\Helper::nonDefaultSubMerchantAccountId(),
  1931. 'creditCard' => [
  1932. 'number' => '5105105105105100',
  1933. 'expirationDate' => '05/12'
  1934. ],
  1935. 'serviceFeeAmount' => '20.00'
  1936. ]);
  1937. $this->assertFalse($result->success);
  1938. $errors = $result->errors->forKey('transaction')->onAttribute('serviceFeeAmount');
  1939. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_SERVICE_FEE_AMOUNT_IS_TOO_LARGE, $errors[0]->code);
  1940. }
  1941. public function testSale_withTooLongPurchaseOrderAttribute()
  1942. {
  1943. $result = Braintree\Transaction::sale([
  1944. 'amount' => '100.00',
  1945. 'creditCard' => [
  1946. 'cardholderName' => 'The Cardholder',
  1947. 'expirationDate' => '05/2011',
  1948. 'number' => '5105105105105100'
  1949. ],
  1950. 'purchaseOrderNumber' => 'aaaaaaaaaaaaaaaaaa'
  1951. ]);
  1952. $this->assertFalse($result->success);
  1953. $purchaseOrderNumberErrors = $result->errors->forKey('transaction')->onAttribute('purchaseOrderNumber');
  1954. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_PURCHASE_ORDER_NUMBER_IS_TOO_LONG, $purchaseOrderNumberErrors[0]->code);
  1955. }
  1956. public function testSale_withInvalidPurchaseOrderNumber()
  1957. {
  1958. $result = Braintree\Transaction::sale([
  1959. 'amount' => '100.00',
  1960. 'creditCard' => [
  1961. 'cardholderName' => 'The Cardholder',
  1962. 'expirationDate' => '05/2011',
  1963. 'number' => '5105105105105100'
  1964. ],
  1965. 'purchaseOrderNumber' => "\x80\x90\xA0"
  1966. ]);
  1967. $this->assertFalse($result->success);
  1968. $purchaseOrderNumberErrors = $result->errors->forKey('transaction')->onAttribute('purchaseOrderNumber');
  1969. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_PURCHASE_ORDER_NUMBER_IS_INVALID, $purchaseOrderNumberErrors[0]->code);
  1970. }
  1971. public function testSale_withAllAttributes()
  1972. {
  1973. $result = Braintree\Transaction::sale([
  1974. 'amount' => '100.00',
  1975. 'orderId' => '123',
  1976. 'channel' => 'MyShoppingCardProvider',
  1977. 'creditCard' => [
  1978. 'cardholderName' => 'The Cardholder',
  1979. 'number' => '5105105105105100',
  1980. 'expirationDate' => '05/2011',
  1981. 'cvv' => '123'
  1982. ],
  1983. 'customer' => [
  1984. 'firstName' => 'Dan',
  1985. 'lastName' => 'Smith',
  1986. 'company' => 'Braintree',
  1987. 'email' => 'dan@example.com',
  1988. 'phone' => '419-555-1234',
  1989. 'fax' => '419-555-1235',
  1990. 'website' => 'http://braintreepayments.com'
  1991. ],
  1992. 'billing' => [
  1993. 'firstName' => 'Carl',
  1994. 'lastName' => 'Jones',
  1995. 'company' => 'Braintree',
  1996. 'streetAddress' => '123 E Main St',
  1997. 'extendedAddress' => 'Suite 403',
  1998. 'locality' => 'Chicago',
  1999. 'region' => 'IL',
  2000. 'postalCode' => '60622',
  2001. 'countryName' => 'United States of America',
  2002. 'countryCodeAlpha2' => 'US',
  2003. 'countryCodeAlpha3' => 'USA',
  2004. 'countryCodeNumeric' => '840'
  2005. ],
  2006. 'shipping' => [
  2007. 'firstName' => 'Andrew',
  2008. 'lastName' => 'Mason',
  2009. 'company' => 'Braintree',
  2010. 'streetAddress' => '456 W Main St',
  2011. 'extendedAddress' => 'Apt 2F',
  2012. 'locality' => 'Bartlett',
  2013. 'region' => 'IL',
  2014. 'postalCode' => '60103',
  2015. 'countryName' => 'United States of America',
  2016. 'countryCodeAlpha2' => 'US',
  2017. 'countryCodeAlpha3' => 'USA',
  2018. 'countryCodeNumeric' => '840'
  2019. ]
  2020. ]);
  2021. Test\Helper::assertPrintable($result);
  2022. $this->assertTrue($result->success);
  2023. $transaction = $result->transaction;
  2024. $this->assertNotNull($transaction->id);
  2025. $this->assertInstanceOf('DateTime', $transaction->updatedAt);
  2026. $this->assertInstanceOf('DateTime', $transaction->createdAt);
  2027. $this->assertNull($transaction->refundId);
  2028. $this->assertEquals(Test\Helper::defaultMerchantAccountId(), $transaction->merchantAccountId);
  2029. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  2030. $this->assertEquals(Braintree\Transaction::SALE, $transaction->type);
  2031. $this->assertEquals('100.00', $transaction->amount);
  2032. $this->assertEquals('USD', $transaction->currencyIsoCode);
  2033. $this->assertEquals('123', $transaction->orderId);
  2034. $this->assertEquals('MyShoppingCardProvider', $transaction->channel);
  2035. $this->assertEquals('MasterCard', $transaction->creditCardDetails->cardType);
  2036. $this->assertEquals('1000', $transaction->processorResponseCode);
  2037. $this->assertEquals('Approved', $transaction->processorResponseText);
  2038. $this->assertNull($transaction->voiceReferralNumber);
  2039. $this->assertFalse($transaction->taxExempt);
  2040. $this->assertEquals('M', $transaction->avsPostalCodeResponseCode);
  2041. $this->assertEquals('M', $transaction->avsStreetAddressResponseCode);
  2042. $this->assertEquals('M', $transaction->cvvResponseCode);
  2043. $this->assertEquals('Dan', $transaction->customerDetails->firstName);
  2044. $this->assertEquals('Smith', $transaction->customerDetails->lastName);
  2045. $this->assertEquals('Braintree', $transaction->customerDetails->company);
  2046. $this->assertEquals('dan@example.com', $transaction->customerDetails->email);
  2047. $this->assertEquals('419-555-1234', $transaction->customerDetails->phone);
  2048. $this->assertEquals('419-555-1235', $transaction->customerDetails->fax);
  2049. $this->assertEquals('http://braintreepayments.com', $transaction->customerDetails->website);
  2050. $this->assertEquals('Carl', $transaction->billingDetails->firstName);
  2051. $this->assertEquals('Jones', $transaction->billingDetails->lastName);
  2052. $this->assertEquals('Braintree', $transaction->billingDetails->company);
  2053. $this->assertEquals('123 E Main St', $transaction->billingDetails->streetAddress);
  2054. $this->assertEquals('Suite 403', $transaction->billingDetails->extendedAddress);
  2055. $this->assertEquals('Chicago', $transaction->billingDetails->locality);
  2056. $this->assertEquals('IL', $transaction->billingDetails->region);
  2057. $this->assertEquals('60622', $transaction->billingDetails->postalCode);
  2058. $this->assertEquals('United States of America', $transaction->billingDetails->countryName);
  2059. $this->assertEquals('US', $transaction->billingDetails->countryCodeAlpha2);
  2060. $this->assertEquals('USA', $transaction->billingDetails->countryCodeAlpha3);
  2061. $this->assertEquals('840', $transaction->billingDetails->countryCodeNumeric);
  2062. $this->assertEquals('Andrew', $transaction->shippingDetails->firstName);
  2063. $this->assertEquals('Mason', $transaction->shippingDetails->lastName);
  2064. $this->assertEquals('Braintree', $transaction->shippingDetails->company);
  2065. $this->assertEquals('456 W Main St', $transaction->shippingDetails->streetAddress);
  2066. $this->assertEquals('Apt 2F', $transaction->shippingDetails->extendedAddress);
  2067. $this->assertEquals('Bartlett', $transaction->shippingDetails->locality);
  2068. $this->assertEquals('IL', $transaction->shippingDetails->region);
  2069. $this->assertEquals('60103', $transaction->shippingDetails->postalCode);
  2070. $this->assertEquals('United States of America', $transaction->shippingDetails->countryName);
  2071. $this->assertEquals('US', $transaction->shippingDetails->countryCodeAlpha2);
  2072. $this->assertEquals('USA', $transaction->shippingDetails->countryCodeAlpha3);
  2073. $this->assertEquals('840', $transaction->shippingDetails->countryCodeNumeric);
  2074. $this->assertNotNull($transaction->processorAuthorizationCode);
  2075. $this->assertEquals('510510', $transaction->creditCardDetails->bin);
  2076. $this->assertEquals('5100', $transaction->creditCardDetails->last4);
  2077. $this->assertEquals('510510******5100', $transaction->creditCardDetails->maskedNumber);
  2078. $this->assertEquals('The Cardholder', $transaction->creditCardDetails->cardholderName);
  2079. $this->assertEquals('05', $transaction->creditCardDetails->expirationMonth);
  2080. $this->assertEquals('2011', $transaction->creditCardDetails->expirationYear);
  2081. $this->assertNotNull($transaction->creditCardDetails->imageUrl);
  2082. }
  2083. public function testSale_withCustomFields()
  2084. {
  2085. $result = Braintree\Transaction::sale([
  2086. 'amount' => '100.00',
  2087. 'creditCard' => [
  2088. 'number' => '5105105105105100',
  2089. 'expirationDate' => '05/12'
  2090. ],
  2091. 'customFields' => [
  2092. 'store_me' => 'custom value'
  2093. ]
  2094. ]);
  2095. $this->assertTrue($result->success);
  2096. $transaction = $result->transaction;
  2097. $customFields = $transaction->customFields;
  2098. $this->assertEquals('custom value', $customFields['store_me']);
  2099. }
  2100. public function testSale_withExpirationMonthAndYear()
  2101. {
  2102. $result = Braintree\Transaction::sale([
  2103. 'amount' => '100.00',
  2104. 'creditCard' => [
  2105. 'number' => '5105105105105100',
  2106. 'expirationMonth' => '5',
  2107. 'expirationYear' => '2012'
  2108. ]
  2109. ]);
  2110. $this->assertTrue($result->success);
  2111. $transaction = $result->transaction;
  2112. $this->assertEquals('05', $transaction->creditCardDetails->expirationMonth);
  2113. $this->assertEquals('2012', $transaction->creditCardDetails->expirationYear);
  2114. }
  2115. public function testSale_underscoresAllCustomFields()
  2116. {
  2117. $result = Braintree\Transaction::sale([
  2118. 'amount' => '100.00',
  2119. 'creditCard' => [
  2120. 'number' => '5105105105105100',
  2121. 'expirationDate' => '05/12'
  2122. ],
  2123. 'customFields' => [
  2124. 'storeMe' => 'custom value'
  2125. ]
  2126. ]);
  2127. $this->assertTrue($result->success);
  2128. $transaction = $result->transaction;
  2129. $customFields = $transaction->customFields;
  2130. $this->assertEquals('custom value', $customFields['store_me']);
  2131. }
  2132. public function testSale_withInvalidCustomField()
  2133. {
  2134. $result = Braintree\Transaction::sale([
  2135. 'amount' => '100.00',
  2136. 'creditCard' => [
  2137. 'number' => '5105105105105100',
  2138. 'expirationDate' => '05/12'
  2139. ],
  2140. 'customFields' => [
  2141. 'invalidKey' => 'custom value'
  2142. ]
  2143. ]);
  2144. $this->assertFalse($result->success);
  2145. $errors = $result->errors->forKey('transaction')->onAttribute('customFields');
  2146. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_CUSTOM_FIELD_IS_INVALID, $errors[0]->code);
  2147. $this->assertEquals('Custom field is invalid: invalidKey.', $errors[0]->message);
  2148. }
  2149. public function testSale_withMerchantAccountId()
  2150. {
  2151. $result = Braintree\Transaction::sale([
  2152. 'amount' => '100.00',
  2153. 'merchantAccountId' => Test\Helper::nonDefaultMerchantAccountId(),
  2154. 'creditCard' => [
  2155. 'number' => '5105105105105100',
  2156. 'expirationDate' => '05/12'
  2157. ]
  2158. ]);
  2159. $this->assertTrue($result->success);
  2160. $transaction = $result->transaction;
  2161. $this->assertEquals(Test\Helper::nonDefaultMerchantAccountId(), $transaction->merchantAccountId);
  2162. }
  2163. public function testSale_withoutMerchantAccountIdFallsBackToDefault()
  2164. {
  2165. $result = Braintree\Transaction::sale([
  2166. 'amount' => '100.00',
  2167. 'creditCard' => [
  2168. 'number' => '5105105105105100',
  2169. 'expirationDate' => '05/12'
  2170. ]
  2171. ]);
  2172. $this->assertTrue($result->success);
  2173. $transaction = $result->transaction;
  2174. $this->assertEquals(Test\Helper::defaultMerchantAccountId(), $transaction->merchantAccountId);
  2175. }
  2176. public function testSale_withShippingAddressId()
  2177. {
  2178. $customer = Braintree\Customer::create([
  2179. 'firstName' => 'Mike',
  2180. 'creditCard' => [
  2181. 'cardholderName' => 'The Cardholder',
  2182. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  2183. 'expirationDate' => '05/12'
  2184. ]
  2185. ])->customer;
  2186. $address = Braintree\Address::create([
  2187. 'customerId' => $customer->id,
  2188. 'streetAddress' => '123 Fake St.'
  2189. ])->address;
  2190. $result = Braintree\Transaction::sale([
  2191. 'amount' => '100.00',
  2192. 'customerId' => $customer->id,
  2193. 'shippingAddressId' => $address->id
  2194. ]);
  2195. $this->assertTrue($result->success);
  2196. $transaction = $result->transaction;
  2197. $this->assertEquals('123 Fake St.', $transaction->shippingDetails->streetAddress);
  2198. $this->assertEquals($address->id, $transaction->shippingDetails->id);
  2199. }
  2200. public function testSale_withBillingAddressId()
  2201. {
  2202. $customer = Braintree\Customer::create([
  2203. 'firstName' => 'Mike',
  2204. 'creditCard' => [
  2205. 'cardholderName' => 'The Cardholder',
  2206. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  2207. 'expirationDate' => '05/12'
  2208. ]
  2209. ])->customer;
  2210. $address = Braintree\Address::create([
  2211. 'customerId' => $customer->id,
  2212. 'streetAddress' => '123 Fake St.'
  2213. ])->address;
  2214. $result = Braintree\Transaction::sale([
  2215. 'amount' => '100.00',
  2216. 'customerId' => $customer->id,
  2217. 'billingAddressId' => $address->id
  2218. ]);
  2219. $this->assertTrue($result->success);
  2220. $transaction = $result->transaction;
  2221. $this->assertEquals('123 Fake St.', $transaction->billingDetails->streetAddress);
  2222. $this->assertEquals($address->id, $transaction->billingDetails->id);
  2223. }
  2224. public function testSaleNoValidate()
  2225. {
  2226. $transaction = Braintree\Transaction::saleNoValidate([
  2227. 'amount' => '100.00',
  2228. 'creditCard' => [
  2229. 'number' => '5105105105105100',
  2230. 'expirationDate' => '05/12'
  2231. ]
  2232. ]);
  2233. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  2234. $this->assertEquals(Braintree\Transaction::SALE, $transaction->type);
  2235. $this->assertEquals('100.00', $transaction->amount);
  2236. $this->assertEquals('510510', $transaction->creditCardDetails->bin);
  2237. $this->assertEquals('5100', $transaction->creditCardDetails->last4);
  2238. }
  2239. public function testSale_withProcessorDecline()
  2240. {
  2241. $gateway = Test\Helper::integrationMerchantGateway();
  2242. $result = $gateway->transaction()->sale([
  2243. 'amount' => Braintree\Test\TransactionAmounts::$decline,
  2244. 'creditCard' => [
  2245. 'number' => '5105105105105100',
  2246. 'expirationDate' => '05/12'
  2247. ],
  2248. ]);
  2249. $this->assertFalse($result->success);
  2250. $this->assertEquals(Braintree\Transaction::PROCESSOR_DECLINED, $result->transaction->status);
  2251. $this->assertEquals(2000, $result->transaction->processorResponseCode);
  2252. $this->assertEquals("Do Not Honor", $result->transaction->processorResponseText);
  2253. $this->assertEquals("2000 : Do Not Honor", $result->transaction->additionalProcessorResponse);
  2254. }
  2255. public function testSale_withExistingCustomer()
  2256. {
  2257. $customer = Braintree\Customer::create([
  2258. 'firstName' => 'Mike',
  2259. 'lastName' => 'Jones',
  2260. 'company' => 'Jones Co.',
  2261. 'email' => 'mike.jones@example.com',
  2262. 'phone' => '419.555.1234',
  2263. 'fax' => '419.555.1235',
  2264. 'website' => 'http://example.com'
  2265. ])->customer;
  2266. $transaction = Braintree\Transaction::sale([
  2267. 'amount' => '100.00',
  2268. 'customerId' => $customer->id,
  2269. 'creditCard' => [
  2270. 'cardholderName' => 'The Cardholder',
  2271. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  2272. 'expirationDate' => '05/12'
  2273. ]
  2274. ])->transaction;
  2275. $this->assertEquals($transaction->creditCardDetails->maskedNumber, '401288******1881');
  2276. $this->assertNull($transaction->vaultCreditCard());
  2277. }
  2278. public function testSale_andStoreShippingAddressInVault()
  2279. {
  2280. $customer = Braintree\Customer::create([
  2281. 'firstName' => 'Mike',
  2282. 'lastName' => 'Jones',
  2283. 'company' => 'Jones Co.',
  2284. 'email' => 'mike.jones@example.com',
  2285. 'phone' => '419.555.1234',
  2286. 'fax' => '419.555.1235',
  2287. 'website' => 'http://example.com'
  2288. ])->customer;
  2289. $transaction = Braintree\Transaction::sale([
  2290. 'amount' => '100.00',
  2291. 'customerId' => $customer->id,
  2292. 'creditCard' => [
  2293. 'cardholderName' => 'The Cardholder',
  2294. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  2295. 'expirationDate' => '05/12'
  2296. ],
  2297. 'shipping' => [
  2298. 'firstName' => 'Darren',
  2299. 'lastName' => 'Stevens'
  2300. ],
  2301. 'options' => [
  2302. 'storeInVault' => true,
  2303. 'storeShippingAddressInVault' => true
  2304. ]
  2305. ])->transaction;
  2306. $customer = Braintree\Customer::find($customer->id);
  2307. $this->assertEquals('Darren', $customer->addresses[0]->firstName);
  2308. $this->assertEquals('Stevens', $customer->addresses[0]->lastName);
  2309. }
  2310. public function testSale_withExistingCustomer_storeInVault()
  2311. {
  2312. $customer = Braintree\Customer::create([
  2313. 'firstName' => 'Mike',
  2314. 'lastName' => 'Jones',
  2315. 'company' => 'Jones Co.',
  2316. 'email' => 'mike.jones@example.com',
  2317. 'phone' => '419.555.1234',
  2318. 'fax' => '419.555.1235',
  2319. 'website' => 'http://example.com'
  2320. ])->customer;
  2321. $transaction = Braintree\Transaction::sale([
  2322. 'amount' => '100.00',
  2323. 'customerId' => $customer->id,
  2324. 'creditCard' => [
  2325. 'cardholderName' => 'The Cardholder',
  2326. 'number' => Braintree\Test\CreditCardNumbers::$visa,
  2327. 'expirationDate' => '05/12'
  2328. ],
  2329. 'options' => [
  2330. 'storeInVault' => true
  2331. ]
  2332. ])->transaction;
  2333. $this->assertEquals($transaction->creditCardDetails->maskedNumber, '401288******1881');
  2334. $this->assertEquals($transaction->vaultCreditCard()->maskedNumber, '401288******1881');
  2335. }
  2336. public function testCredit()
  2337. {
  2338. $result = Braintree\Transaction::credit([
  2339. 'amount' => '100.00',
  2340. 'creditCard' => [
  2341. 'number' => '5105105105105100',
  2342. 'expirationDate' => '05/12'
  2343. ]
  2344. ]);
  2345. $this->assertTrue($result->success);
  2346. $transaction = $result->transaction;
  2347. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $transaction->status);
  2348. $this->assertEquals(Braintree\Transaction::CREDIT, $transaction->type);
  2349. $this->assertEquals('100.00', $transaction->amount);
  2350. $this->assertEquals('510510', $transaction->creditCardDetails->bin);
  2351. $this->assertEquals('5100', $transaction->creditCardDetails->last4);
  2352. }
  2353. public function testCreditNoValidate()
  2354. {
  2355. $transaction = Braintree\Transaction::creditNoValidate([
  2356. 'amount' => '100.00',
  2357. 'creditCard' => [
  2358. 'number' => '5105105105105100',
  2359. 'expirationDate' => '05/12'
  2360. ]
  2361. ]);
  2362. $this->assertEquals(Braintree\Transaction::CREDIT, $transaction->type);
  2363. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $transaction->status);
  2364. $this->assertEquals('100.00', $transaction->amount);
  2365. $this->assertEquals('510510', $transaction->creditCardDetails->bin);
  2366. $this->assertEquals('5100', $transaction->creditCardDetails->last4);
  2367. }
  2368. public function testCredit_withMerchantAccountId()
  2369. {
  2370. $result = Braintree\Transaction::credit([
  2371. 'amount' => '100.00',
  2372. 'merchantAccountId' => Test\Helper::nonDefaultMerchantAccountId(),
  2373. 'creditCard' => [
  2374. 'number' => '5105105105105100',
  2375. 'expirationDate' => '05/12'
  2376. ]
  2377. ]);
  2378. $this->assertTrue($result->success);
  2379. $transaction = $result->transaction;
  2380. $this->assertEquals(Test\Helper::nonDefaultMerchantAccountId(), $transaction->merchantAccountId);
  2381. }
  2382. public function testCredit_withoutMerchantAccountIdFallsBackToDefault()
  2383. {
  2384. $result = Braintree\Transaction::credit([
  2385. 'amount' => '100.00',
  2386. 'creditCard' => [
  2387. 'number' => '5105105105105100',
  2388. 'expirationDate' => '05/12'
  2389. ]
  2390. ]);
  2391. $this->assertTrue($result->success);
  2392. $transaction = $result->transaction;
  2393. $this->assertEquals(Test\Helper::defaultMerchantAccountId(), $transaction->merchantAccountId);
  2394. }
  2395. public function testCredit_withServiceFeeNotAllowed()
  2396. {
  2397. $result = Braintree\Transaction::credit([
  2398. 'amount' => '100.00',
  2399. 'creditCard' => [
  2400. 'number' => '5105105105105100',
  2401. 'expirationDate' => '05/12'
  2402. ],
  2403. 'serviceFeeAmount' => '12.75'
  2404. ]);
  2405. $this->assertFalse($result->success);
  2406. $errors = $result->errors->forKey('transaction')->onAttribute('base');
  2407. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_SERVICE_FEE_IS_NOT_ALLOWED_ON_CREDITS, $errors[0]->code);
  2408. }
  2409. public function testSubmitForSettlement_nullAmount()
  2410. {
  2411. $transaction = Braintree\Transaction::saleNoValidate([
  2412. 'amount' => '100.00',
  2413. 'creditCard' => [
  2414. 'number' => '5105105105105100',
  2415. 'expirationDate' => '05/12'
  2416. ]
  2417. ]);
  2418. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  2419. $submitResult = Braintree\Transaction::submitForSettlement($transaction->id);
  2420. $this->assertEquals(true, $submitResult->success);
  2421. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $submitResult->transaction->status);
  2422. $this->assertEquals('100.00', $submitResult->transaction->amount);
  2423. }
  2424. public function testSubmitForSettlement_amountLessThanServiceFee()
  2425. {
  2426. $transaction = Braintree\Transaction::saleNoValidate([
  2427. 'amount' => '10.00',
  2428. 'merchantAccountId' => Test\Helper::nonDefaultSubMerchantAccountId(),
  2429. 'creditCard' => [
  2430. 'number' => '5105105105105100',
  2431. 'expirationDate' => '05/12'
  2432. ],
  2433. 'serviceFeeAmount' => '5.00'
  2434. ]);
  2435. $submitResult = Braintree\Transaction::submitForSettlement($transaction->id, '1.00');
  2436. $errors = $submitResult->errors->forKey('transaction')->onAttribute('amount');
  2437. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_SETTLEMENT_AMOUNT_IS_LESS_THAN_SERVICE_FEE_AMOUNT, $errors[0]->code);
  2438. }
  2439. public function testSubmitForSettlement_withAmount()
  2440. {
  2441. $transaction = Braintree\Transaction::saleNoValidate([
  2442. 'amount' => '100.00',
  2443. 'creditCard' => [
  2444. 'number' => '5105105105105100',
  2445. 'expirationDate' => '05/12'
  2446. ]
  2447. ]);
  2448. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  2449. $submitResult = Braintree\Transaction::submitForSettlement($transaction->id, '50.00');
  2450. $this->assertEquals(true, $submitResult->success);
  2451. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $submitResult->transaction->status);
  2452. $this->assertEquals('50.00', $submitResult->transaction->amount);
  2453. }
  2454. public function testSubmitForSettlement_withOrderId()
  2455. {
  2456. $transaction = Braintree\Transaction::saleNoValidate([
  2457. 'amount' => '100.00',
  2458. 'creditCard' => [
  2459. 'number' => '5105105105105100',
  2460. 'expirationDate' => '05/12'
  2461. ]
  2462. ]);
  2463. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  2464. $submitResult = Braintree\Transaction::submitForSettlement($transaction->id, '67.00', ['orderId' => 'ABC123']);
  2465. $this->assertEquals(true, $submitResult->success);
  2466. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $submitResult->transaction->status);
  2467. $this->assertEquals('ABC123', $submitResult->transaction->orderId);
  2468. $this->assertEquals('67.00', $submitResult->transaction->amount);
  2469. }
  2470. public function testSubmitForSettlement_withDescriptor()
  2471. {
  2472. $transaction = Braintree\Transaction::saleNoValidate([
  2473. 'amount' => '100.00',
  2474. 'creditCard' => [
  2475. 'number' => '5105105105105100',
  2476. 'expirationDate' => '05/12'
  2477. ]
  2478. ]);
  2479. $params = [
  2480. 'descriptor' => [
  2481. 'name' => '123*123456789012345678',
  2482. 'phone' => '3334445555',
  2483. 'url' => 'ebay.com'
  2484. ]
  2485. ];
  2486. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  2487. $submitResult = Braintree\Transaction::submitForSettlement($transaction->id, '67.00', $params);
  2488. $this->assertEquals(true, $submitResult->success);
  2489. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $submitResult->transaction->status);
  2490. $this->assertEquals('123*123456789012345678', $submitResult->transaction->descriptor->name);
  2491. $this->assertEquals('3334445555', $submitResult->transaction->descriptor->phone);
  2492. $this->assertEquals('ebay.com', $submitResult->transaction->descriptor->url);
  2493. }
  2494. public function testSubmitForSettlement_withInvalidParams()
  2495. {
  2496. $transaction = Braintree\Transaction::saleNoValidate([
  2497. 'amount' => '100.00',
  2498. 'creditCard' => [
  2499. 'number' => '5105105105105100',
  2500. 'expirationDate' => '05/12'
  2501. ]
  2502. ]);
  2503. $params = ['invalid' => 'invalid'];
  2504. $this->setExpectedException('InvalidArgumentException', 'invalid keys: invalid');
  2505. Braintree\Transaction::submitForSettlement($transaction->id, '67.00', $params);
  2506. }
  2507. public function testSubmitForSettlementNoValidate_whenValidWithoutAmount()
  2508. {
  2509. $transaction = Braintree\Transaction::saleNoValidate([
  2510. 'amount' => '100.00',
  2511. 'creditCard' => [
  2512. 'number' => '5105105105105100',
  2513. 'expirationDate' => '05/12'
  2514. ]
  2515. ]);
  2516. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  2517. $submittedTransaction = Braintree\Transaction::submitForSettlementNoValidate($transaction->id);
  2518. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $submittedTransaction->status);
  2519. $this->assertEquals('100.00', $submittedTransaction->amount);
  2520. }
  2521. public function testSubmitForSettlementNoValidate_whenValidWithAmount()
  2522. {
  2523. $transaction = Braintree\Transaction::saleNoValidate([
  2524. 'amount' => '100.00',
  2525. 'creditCard' => [
  2526. 'number' => '5105105105105100',
  2527. 'expirationDate' => '05/12'
  2528. ]
  2529. ]);
  2530. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  2531. $submittedTransaction = Braintree\Transaction::submitForSettlementNoValidate($transaction->id, '99.00');
  2532. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $submittedTransaction->status);
  2533. $this->assertEquals('99.00', $submittedTransaction->amount);
  2534. }
  2535. public function testSubmitForSettlementNoValidate_whenInvalid()
  2536. {
  2537. $transaction = Braintree\Transaction::saleNoValidate([
  2538. 'amount' => '100.00',
  2539. 'creditCard' => [
  2540. 'number' => '5105105105105100',
  2541. 'expirationDate' => '05/12'
  2542. ]
  2543. ]);
  2544. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  2545. $this->setExpectedException('Braintree\Exception\ValidationsFailed');
  2546. $submittedTransaction = Braintree\Transaction::submitForSettlementNoValidate($transaction->id, '101.00');
  2547. }
  2548. public function testUpdateDetails()
  2549. {
  2550. $transaction = Braintree\Transaction::saleNoValidate([
  2551. 'amount' => '100.00',
  2552. 'creditCard' => [
  2553. 'number' => '5105105105105100',
  2554. 'expirationDate' => '05/12'
  2555. ],
  2556. 'options' => [
  2557. 'submitForSettlement' => true
  2558. ]
  2559. ]);
  2560. $updateOptions = [
  2561. 'amount' => '90.00',
  2562. 'orderId' => '123',
  2563. 'descriptor' => [
  2564. 'name' => '123*123456789012345678',
  2565. 'phone' => '3334445555',
  2566. 'url' => 'ebay.com'
  2567. ]
  2568. ];
  2569. $result = Braintree\Transaction::updateDetails($transaction->id, $updateOptions);
  2570. $this->assertEquals(true, $result->success);
  2571. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $result->transaction->status);
  2572. $this->assertEquals('90.00', $result->transaction->amount);
  2573. }
  2574. public function testUpdateDetails_withInvalidParams()
  2575. {
  2576. $transaction = Braintree\Transaction::saleNoValidate([
  2577. 'amount' => '100.00',
  2578. 'creditCard' => [
  2579. 'number' => '5105105105105100',
  2580. 'expirationDate' => '05/12'
  2581. ],
  2582. 'options' => [
  2583. 'submitForSettlement' => true
  2584. ]
  2585. ]);
  2586. $updateOptions = [
  2587. 'amount' => '90.00',
  2588. 'invalid' => 'some value'
  2589. ];
  2590. $this->setExpectedException('InvalidArgumentException', 'invalid keys: invalid');
  2591. Braintree\Transaction::updateDetails($transaction->id, $updateOptions);
  2592. }
  2593. public function testUpdateDetails_withInvalidAmount()
  2594. {
  2595. $transaction = Braintree\Transaction::saleNoValidate([
  2596. 'amount' => '100.00',
  2597. 'creditCard' => [
  2598. 'number' => '5105105105105100',
  2599. 'expirationDate' => '05/12'
  2600. ],
  2601. 'options' => [
  2602. 'submitForSettlement' => true
  2603. ]
  2604. ]);
  2605. $updateOptions = [
  2606. 'amount' => '900.00',
  2607. 'orderId' => '123',
  2608. 'descriptor' => [
  2609. 'name' => '123*123456789012345678',
  2610. 'phone' => '3334445555',
  2611. 'url' => 'ebay.com'
  2612. ]
  2613. ];
  2614. $result = Braintree\Transaction::updateDetails($transaction->id, $updateOptions);
  2615. $this->assertFalse($result->success);
  2616. $errors = $result->errors->forKey('transaction')->onAttribute('amount');
  2617. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_SETTLEMENT_AMOUNT_IS_TOO_LARGE, $errors[0]->code);
  2618. }
  2619. public function testUpdateDetails_withInvalidDescriptor()
  2620. {
  2621. $transaction = Braintree\Transaction::saleNoValidate([
  2622. 'amount' => '100.00',
  2623. 'creditCard' => [
  2624. 'number' => '5105105105105100',
  2625. 'expirationDate' => '05/12'
  2626. ],
  2627. 'options' => [
  2628. 'submitForSettlement' => true
  2629. ]
  2630. ]);
  2631. $updateOptions = [
  2632. 'amount' => '90.00',
  2633. 'orderId' => '123',
  2634. 'descriptor' => [
  2635. 'name' => 'invalid name',
  2636. 'phone' => 'invalid phone',
  2637. 'url' => 'invalid way too long url'
  2638. ]
  2639. ];
  2640. $result = Braintree\Transaction::updateDetails($transaction->id, $updateOptions);
  2641. $this->assertFalse($result->success);
  2642. $errors = $result->errors->forKey('transaction')->forKey('descriptor')->onAttribute('name');
  2643. $this->assertEquals(Braintree\Error\Codes::DESCRIPTOR_NAME_FORMAT_IS_INVALID, $errors[0]->code);
  2644. $errors = $result->errors->forKey('transaction')->forKey('descriptor')->onAttribute('phone');
  2645. $this->assertEquals(Braintree\Error\Codes::DESCRIPTOR_PHONE_FORMAT_IS_INVALID, $errors[0]->code);
  2646. $errors = $result->errors->forKey('transaction')->forKey('descriptor')->onAttribute('url');
  2647. $this->assertEquals(Braintree\Error\Codes::DESCRIPTOR_URL_FORMAT_IS_INVALID, $errors[0]->code);
  2648. }
  2649. public function testUpdateDetails_withInvalidOrderId()
  2650. {
  2651. $transaction = Braintree\Transaction::saleNoValidate([
  2652. 'amount' => '100.00',
  2653. 'creditCard' => [
  2654. 'number' => '5105105105105100',
  2655. 'expirationDate' => '05/12'
  2656. ],
  2657. 'options' => [
  2658. 'submitForSettlement' => true
  2659. ]
  2660. ]);
  2661. $updateOptions = [
  2662. 'amount' => '90.00',
  2663. 'orderId' => str_repeat('x', 256),
  2664. 'descriptor' => [
  2665. 'name' => '123*123456789012345678',
  2666. 'phone' => '3334445555',
  2667. 'url' => 'ebay.com'
  2668. ]
  2669. ];
  2670. $result = Braintree\Transaction::updateDetails($transaction->id, $updateOptions);
  2671. $this->assertFalse($result->success);
  2672. $errors = $result->errors->forKey('transaction')->onAttribute('orderId');
  2673. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_ORDER_ID_IS_TOO_LONG, $errors[0]->code);
  2674. }
  2675. public function testUpdateDetails_withInvalidProcessor()
  2676. {
  2677. $transaction = Braintree\Transaction::saleNoValidate([
  2678. 'amount' => '100.00',
  2679. 'merchantAccountId' => Test\Helper::fakeAmexDirectMerchantAccountId(),
  2680. 'creditCard' => [
  2681. 'cardholderName' => 'The Cardholder',
  2682. 'number' => Braintree\Test\CreditCardNumbers::$amexPayWithPoints['Success'],
  2683. 'expirationDate' => '05/12'
  2684. ],
  2685. 'options' => [
  2686. 'submitForSettlement' => true
  2687. ]
  2688. ]);
  2689. $updateOptions = [
  2690. 'amount' => '90.00',
  2691. 'orderId' => '123',
  2692. 'descriptor' => [
  2693. 'name' => '123*123456789012345678',
  2694. 'phone' => '3334445555',
  2695. 'url' => 'ebay.com'
  2696. ]
  2697. ];
  2698. $result = Braintree\Transaction::updateDetails($transaction->id, $updateOptions);
  2699. $this->assertFalse($result->success);
  2700. $errors = $result->errors->forKey('transaction')->onAttribute('base');
  2701. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_PROCESSOR_DOES_NOT_SUPPORT_UPDATING_DETAILS, $errors[0]->code);
  2702. }
  2703. public function testUpdateDetails_withBadStatus()
  2704. {
  2705. $transaction = Braintree\Transaction::saleNoValidate([
  2706. 'amount' => '100.00',
  2707. 'creditCard' => [
  2708. 'number' => '5105105105105100',
  2709. 'expirationDate' => '05/12'
  2710. ]
  2711. ]);
  2712. $updateOptions = [
  2713. 'amount' => '90.00',
  2714. 'orderId' => '123',
  2715. 'descriptor' => [
  2716. 'name' => '123*123456789012345678',
  2717. 'phone' => '3334445555',
  2718. 'url' => 'ebay.com'
  2719. ]
  2720. ];
  2721. $result = Braintree\Transaction::updateDetails($transaction->id, $updateOptions);
  2722. $this->assertFalse($result->success);
  2723. $errors = $result->errors->forKey('transaction')->onAttribute('base');
  2724. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_CANNOT_UPDATE_DETAILS_NOT_SUBMITTED_FOR_SETTLEMENT, $errors[0]->code);
  2725. }
  2726. public function testVoid()
  2727. {
  2728. $transaction = Braintree\Transaction::saleNoValidate([
  2729. 'amount' => '100.00',
  2730. 'creditCard' => [
  2731. 'number' => '5105105105105100',
  2732. 'expirationDate' => '05/12'
  2733. ]
  2734. ]);
  2735. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  2736. $voidResult = Braintree\Transaction::void($transaction->id);
  2737. $this->assertEquals(true, $voidResult->success);
  2738. $this->assertEquals(Braintree\Transaction::VOIDED, $voidResult->transaction->status);
  2739. }
  2740. public function test_countryValidationError_inconsistency()
  2741. {
  2742. $result = Braintree\Transaction::sale([
  2743. 'amount' => '100.00',
  2744. 'creditCard' => [
  2745. 'number' => '5105105105105100',
  2746. 'expirationDate' => '05/12'
  2747. ],
  2748. 'billing' => [
  2749. 'countryCodeAlpha2' => 'AS',
  2750. 'countryCodeAlpha3' => 'USA'
  2751. ]
  2752. ]);
  2753. $this->assertFalse($result->success);
  2754. $errors = $result->errors->forKey('transaction')->forKey('billing')->onAttribute('base');
  2755. $this->assertEquals(Braintree\Error\Codes::ADDRESS_INCONSISTENT_COUNTRY, $errors[0]->code);
  2756. }
  2757. public function test_countryValidationError_incorrectAlpha2()
  2758. {
  2759. $result = Braintree\Transaction::sale([
  2760. 'amount' => '100.00',
  2761. 'creditCard' => [
  2762. 'number' => '5105105105105100',
  2763. 'expirationDate' => '05/12'
  2764. ],
  2765. 'billing' => [
  2766. 'countryCodeAlpha2' => 'ZZ'
  2767. ]
  2768. ]);
  2769. $this->assertFalse($result->success);
  2770. $errors = $result->errors->forKey('transaction')->forKey('billing')->onAttribute('countryCodeAlpha2');
  2771. $this->assertEquals(Braintree\Error\Codes::ADDRESS_COUNTRY_CODE_ALPHA2_IS_NOT_ACCEPTED, $errors[0]->code);
  2772. }
  2773. public function test_countryValidationError_incorrectAlpha3()
  2774. {
  2775. $result = Braintree\Transaction::sale([
  2776. 'amount' => '100.00',
  2777. 'creditCard' => [
  2778. 'number' => '5105105105105100',
  2779. 'expirationDate' => '05/12'
  2780. ],
  2781. 'billing' => [
  2782. 'countryCodeAlpha3' => 'ZZZ'
  2783. ]
  2784. ]);
  2785. $this->assertFalse($result->success);
  2786. $errors = $result->errors->forKey('transaction')->forKey('billing')->onAttribute('countryCodeAlpha3');
  2787. $this->assertEquals(Braintree\Error\Codes::ADDRESS_COUNTRY_CODE_ALPHA3_IS_NOT_ACCEPTED, $errors[0]->code);
  2788. }
  2789. public function test_countryValidationError_incorrectNumericCode()
  2790. {
  2791. $result = Braintree\Transaction::sale([
  2792. 'amount' => '100.00',
  2793. 'creditCard' => [
  2794. 'number' => '5105105105105100',
  2795. 'expirationDate' => '05/12'
  2796. ],
  2797. 'billing' => [
  2798. 'countryCodeNumeric' => '000'
  2799. ]
  2800. ]);
  2801. $this->assertFalse($result->success);
  2802. $errors = $result->errors->forKey('transaction')->forKey('billing')->onAttribute('countryCodeNumeric');
  2803. $this->assertEquals(Braintree\Error\Codes::ADDRESS_COUNTRY_CODE_NUMERIC_IS_NOT_ACCEPTED, $errors[0]->code);
  2804. }
  2805. public function testVoid_withValidationError()
  2806. {
  2807. $transaction = Braintree\Transaction::saleNoValidate([
  2808. 'amount' => '100.00',
  2809. 'creditCard' => [
  2810. 'number' => '5105105105105100',
  2811. 'expirationDate' => '05/12'
  2812. ]
  2813. ]);
  2814. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  2815. $voided = Braintree\Transaction::voidNoValidate($transaction->id);
  2816. $this->assertEquals(Braintree\Transaction::VOIDED, $voided->status);
  2817. $result = Braintree\Transaction::void($transaction->id);
  2818. $this->assertEquals(false, $result->success);
  2819. $errors = $result->errors->forKey('transaction')->onAttribute('base');
  2820. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_CANNOT_BE_VOIDED, $errors[0]->code);
  2821. }
  2822. public function testVoidNoValidate()
  2823. {
  2824. $transaction = Braintree\Transaction::saleNoValidate([
  2825. 'amount' => '100.00',
  2826. 'creditCard' => [
  2827. 'number' => '5105105105105100',
  2828. 'expirationDate' => '05/12'
  2829. ]
  2830. ]);
  2831. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  2832. $voided = Braintree\Transaction::voidNoValidate($transaction->id);
  2833. $this->assertEquals(Braintree\Transaction::VOIDED, $voided->status);
  2834. }
  2835. public function testVoidNoValidate_throwsIfNotInvalid()
  2836. {
  2837. $transaction = Braintree\Transaction::saleNoValidate([
  2838. 'amount' => '100.00',
  2839. 'creditCard' => [
  2840. 'number' => '5105105105105100',
  2841. 'expirationDate' => '05/12'
  2842. ]
  2843. ]);
  2844. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  2845. $voided = Braintree\Transaction::voidNoValidate($transaction->id);
  2846. $this->assertEquals(Braintree\Transaction::VOIDED, $voided->status);
  2847. $this->setExpectedException('Braintree\Exception\ValidationsFailed');
  2848. $voided = Braintree\Transaction::voidNoValidate($transaction->id);
  2849. }
  2850. public function testFind()
  2851. {
  2852. $result = Braintree\Transaction::sale([
  2853. 'amount' => '100.00',
  2854. 'creditCard' => [
  2855. 'number' => '5105105105105100',
  2856. 'expirationDate' => '05/12'
  2857. ]
  2858. ]);
  2859. $transaction = Braintree\Transaction::find($result->transaction->id);
  2860. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  2861. $this->assertEquals(Braintree\Transaction::SALE, $transaction->type);
  2862. $this->assertEquals('100.00', $transaction->amount);
  2863. $this->assertEquals('510510', $transaction->creditCardDetails->bin);
  2864. $this->assertEquals('5100', $transaction->creditCardDetails->last4);
  2865. }
  2866. public function testFindExposesDisbursementDetails()
  2867. {
  2868. $transaction = Braintree\Transaction::find("deposittransaction");
  2869. $this->assertEquals(true, $transaction->isDisbursed());
  2870. $disbursementDetails = $transaction->disbursementDetails;
  2871. $this->assertEquals('100.00', $disbursementDetails->settlementAmount);
  2872. $this->assertEquals('USD', $disbursementDetails->settlementCurrencyIsoCode);
  2873. $this->assertEquals('1', $disbursementDetails->settlementCurrencyExchangeRate);
  2874. $this->assertEquals(false, $disbursementDetails->fundsHeld);
  2875. $this->assertEquals(true, $disbursementDetails->success);
  2876. $this->assertEquals(new DateTime('2013-04-10'), $disbursementDetails->disbursementDate);
  2877. }
  2878. public function testFindExposesAuthorizationAdjustments()
  2879. {
  2880. $transaction = Braintree\Transaction::find("authadjustmenttransaction");
  2881. $authorizationAdjustment = $transaction->authorizationAdjustments[0];
  2882. $this->assertEquals('-20.00', $authorizationAdjustment->amount);
  2883. $this->assertInstanceOf('DateTime', $authorizationAdjustment->timestamp);
  2884. $this->assertEquals(true, $authorizationAdjustment->success);
  2885. $this->assertEquals('1000', $authorizationAdjustment->processorResponseCode);
  2886. $this->assertEquals('Approved', $authorizationAdjustment->processorResponseText);
  2887. }
  2888. public function testFindExposesDisputes()
  2889. {
  2890. $transaction = Braintree\Transaction::find("disputedtransaction");
  2891. $dispute = $transaction->disputes[0];
  2892. $this->assertEquals('250.00', $dispute->amount);
  2893. $this->assertEquals('USD', $dispute->currencyIsoCode);
  2894. $this->assertEquals(Braintree\Dispute::FRAUD, $dispute->reason);
  2895. $this->assertEquals(Braintree\Dispute::WON, $dispute->status);
  2896. $this->assertEquals(new DateTime('2014-03-01'), $dispute->receivedDate);
  2897. $this->assertEquals(new DateTime('2014-03-21'), $dispute->replyByDate);
  2898. $this->assertEquals("disputedtransaction", $dispute->transactionDetails->id);
  2899. $this->assertEquals("1000.00", $dispute->transactionDetails->amount);
  2900. $this->assertEquals(Braintree\Dispute::CHARGEBACK, $dispute->kind);
  2901. $this->assertEquals(new DateTime('2014-03-01'), $dispute->dateOpened);
  2902. $this->assertEquals(new DateTime('2014-03-07'), $dispute->dateWon);
  2903. }
  2904. public function testFindExposesThreeDSecureInfo()
  2905. {
  2906. $transaction = Braintree\Transaction::find("threedsecuredtransaction");
  2907. $info = $transaction->threeDSecureInfo;
  2908. $this->assertEquals("Y", $info->enrolled);
  2909. $this->assertEquals("authenticate_successful", $info->status);
  2910. $this->assertTrue($info->liabilityShifted);
  2911. $this->assertTrue($info->liabilityShiftPossible);
  2912. }
  2913. public function testFindExposesNullThreeDSecureInfo()
  2914. {
  2915. $transaction = Braintree\Transaction::find("settledtransaction");
  2916. $this->assertNull($transaction->threeDSecureInfo);
  2917. }
  2918. public function testFindExposesRetrievals()
  2919. {
  2920. $transaction = Braintree\Transaction::find("retrievaltransaction");
  2921. $dispute = $transaction->disputes[0];
  2922. $this->assertEquals('1000.00', $dispute->amount);
  2923. $this->assertEquals('USD', $dispute->currencyIsoCode);
  2924. $this->assertEquals(Braintree\Dispute::RETRIEVAL, $dispute->reason);
  2925. $this->assertEquals(Braintree\Dispute::OPEN, $dispute->status);
  2926. $this->assertEquals("retrievaltransaction", $dispute->transactionDetails->id);
  2927. $this->assertEquals("1000.00", $dispute->transactionDetails->amount);
  2928. }
  2929. public function testFindExposesPayPalDetails()
  2930. {
  2931. $transaction = Braintree\Transaction::find("settledtransaction");
  2932. $this->assertNotNull($transaction->paypalDetails->debugId);
  2933. $this->assertNotNull($transaction->paypalDetails->payerEmail);
  2934. $this->assertNotNull($transaction->paypalDetails->authorizationId);
  2935. $this->assertNotNull($transaction->paypalDetails->payerId);
  2936. $this->assertNotNull($transaction->paypalDetails->payerFirstName);
  2937. $this->assertNotNull($transaction->paypalDetails->payerLastName);
  2938. $this->assertNotNull($transaction->paypalDetails->payerStatus);
  2939. $this->assertNotNull($transaction->paypalDetails->sellerProtectionStatus);
  2940. $this->assertNotNull($transaction->paypalDetails->captureId);
  2941. $this->assertNotNull($transaction->paypalDetails->refundId);
  2942. $this->assertNotNull($transaction->paypalDetails->transactionFeeAmount);
  2943. $this->assertNotNull($transaction->paypalDetails->transactionFeeCurrencyIsoCode);
  2944. }
  2945. public function testSale_storeInVault()
  2946. {
  2947. $transaction = Braintree\Transaction::saleNoValidate([
  2948. 'amount' => '100.00',
  2949. 'creditCard' => [
  2950. 'cardholderName' => 'Card Holder',
  2951. 'number' => '5105105105105100',
  2952. 'expirationDate' => '05/12',
  2953. ],
  2954. 'customer' => [
  2955. 'firstName' => 'Dan',
  2956. 'lastName' => 'Smith',
  2957. 'company' => 'Braintree',
  2958. 'email' => 'dan@example.com',
  2959. 'phone' => '419-555-1234',
  2960. 'fax' => '419-555-1235',
  2961. 'website' => 'http://getbraintree.com'
  2962. ],
  2963. 'options' => [
  2964. 'storeInVault' => true
  2965. ]
  2966. ]);
  2967. $this->assertNotNull($transaction->creditCardDetails->token);
  2968. $creditCard = $transaction->vaultCreditCard();
  2969. $this->assertEquals('510510', $creditCard->bin);
  2970. $this->assertEquals('5100', $creditCard->last4);
  2971. $this->assertEquals('05/2012', $creditCard->expirationDate);
  2972. $this->assertEquals('Card Holder', $creditCard->cardholderName);
  2973. $customer = $transaction->vaultCustomer();
  2974. $this->assertEquals('Dan', $customer->firstName);
  2975. $this->assertEquals('Smith', $customer->lastName);
  2976. $this->assertEquals('Braintree', $customer->company);
  2977. $this->assertEquals('dan@example.com', $customer->email);
  2978. $this->assertEquals('419-555-1234', $customer->phone);
  2979. $this->assertEquals('419-555-1235', $customer->fax);
  2980. $this->assertEquals('http://getbraintree.com', $customer->website);
  2981. }
  2982. public function testSale_storeInVaultOnSuccessWithSuccessfulTransaction()
  2983. {
  2984. $transaction = Braintree\Transaction::saleNoValidate([
  2985. 'amount' => '100.00',
  2986. 'creditCard' => [
  2987. 'cardholderName' => 'Card Holder',
  2988. 'number' => '5105105105105100',
  2989. 'expirationDate' => '05/12',
  2990. ],
  2991. 'customer' => [
  2992. 'firstName' => 'Dan',
  2993. 'lastName' => 'Smith',
  2994. 'company' => 'Braintree',
  2995. 'email' => 'dan@example.com',
  2996. 'phone' => '419-555-1234',
  2997. 'fax' => '419-555-1235',
  2998. 'website' => 'http://getbraintree.com'
  2999. ],
  3000. 'options' => [
  3001. 'storeInVaultOnSuccess' => true
  3002. ]
  3003. ]);
  3004. $this->assertNotNull($transaction->creditCardDetails->token);
  3005. $creditCard = $transaction->vaultCreditCard();
  3006. $this->assertEquals('510510', $creditCard->bin);
  3007. $this->assertEquals('5100', $creditCard->last4);
  3008. $this->assertEquals('05/2012', $creditCard->expirationDate);
  3009. $this->assertEquals('Card Holder', $creditCard->cardholderName);
  3010. $customer = $transaction->vaultCustomer();
  3011. $this->assertEquals('Dan', $customer->firstName);
  3012. $this->assertEquals('Smith', $customer->lastName);
  3013. $this->assertEquals('Braintree', $customer->company);
  3014. $this->assertEquals('dan@example.com', $customer->email);
  3015. $this->assertEquals('419-555-1234', $customer->phone);
  3016. $this->assertEquals('419-555-1235', $customer->fax);
  3017. $this->assertEquals('http://getbraintree.com', $customer->website);
  3018. }
  3019. public function testSale_storeInVaultOnSuccessWithFailedTransaction()
  3020. {
  3021. $result = Braintree\Transaction::sale([
  3022. 'amount' => Braintree\Test\TransactionAmounts::$decline,
  3023. 'creditCard' => [
  3024. 'cardholderName' => 'Card Holder',
  3025. 'number' => '5105105105105100',
  3026. 'expirationDate' => '05/12',
  3027. ],
  3028. 'customer' => [
  3029. 'firstName' => 'Dan',
  3030. 'lastName' => 'Smith',
  3031. 'company' => 'Braintree',
  3032. 'email' => 'dan@example.com',
  3033. 'phone' => '419-555-1234',
  3034. 'fax' => '419-555-1235',
  3035. 'website' => 'http://getbraintree.com'
  3036. ],
  3037. 'options' => [
  3038. 'storeInVaultOnSuccess' => true
  3039. ]
  3040. ]);
  3041. $transaction = $result->transaction;
  3042. $this->assertNull($transaction->creditCardDetails->token);
  3043. $this->assertNull($transaction->vaultCreditCard());
  3044. $this->assertNull($transaction->customerDetails->id);
  3045. $this->assertNull($transaction->vaultCustomer());
  3046. }
  3047. public function testSale_withFraudParams()
  3048. {
  3049. $result = Braintree\Transaction::sale([
  3050. 'deviceSessionId' => '123abc',
  3051. 'fraudMerchantId' => '456',
  3052. 'amount' => '100.00',
  3053. 'creditCard' => [
  3054. 'number' => '5105105105105100',
  3055. 'expirationDate' => '05/12',
  3056. ]
  3057. ]);
  3058. $this->assertTrue($result->success);
  3059. }
  3060. public function testSale_withRiskData()
  3061. {
  3062. $result = Braintree\Transaction::sale([
  3063. 'amount' => '100.00',
  3064. 'creditCard' => [
  3065. 'number' => '5105105105105100',
  3066. 'expirationDate' => '05/12',
  3067. ],
  3068. 'riskData' => [
  3069. 'customer_browser' => 'IE5',
  3070. 'customer_ip' => '192.168.0.1'
  3071. ]
  3072. ]);
  3073. $this->assertTrue($result->success);
  3074. }
  3075. public function testSale_withDescriptor()
  3076. {
  3077. $result = Braintree\Transaction::sale([
  3078. 'amount' => '100.00',
  3079. 'creditCard' => [
  3080. 'number' => '5105105105105100',
  3081. 'expirationDate' => '05/12',
  3082. ],
  3083. 'descriptor' => [
  3084. 'name' => '123*123456789012345678',
  3085. 'phone' => '3334445555',
  3086. 'url' => 'ebay.com'
  3087. ]
  3088. ]);
  3089. $this->assertTrue($result->success);
  3090. $transaction = $result->transaction;
  3091. $this->assertEquals('123*123456789012345678', $transaction->descriptor->name);
  3092. $this->assertEquals('3334445555', $transaction->descriptor->phone);
  3093. $this->assertEquals('ebay.com', $transaction->descriptor->url);
  3094. }
  3095. public function testSale_withDescriptorValidation()
  3096. {
  3097. $result = Braintree\Transaction::sale([
  3098. 'amount' => '100.00',
  3099. 'creditCard' => [
  3100. 'number' => '5105105105105100',
  3101. 'expirationDate' => '05/12',
  3102. ],
  3103. 'descriptor' => [
  3104. 'name' => 'badcompanyname12*badproduct12',
  3105. 'phone' => '%bad4445555',
  3106. 'url' => '12345678901234'
  3107. ]
  3108. ]);
  3109. $this->assertFalse($result->success);
  3110. $transaction = $result->transaction;
  3111. $errors = $result->errors->forKey('transaction')->forKey('descriptor')->onAttribute('name');
  3112. $this->assertEquals(Braintree\Error\Codes::DESCRIPTOR_NAME_FORMAT_IS_INVALID, $errors[0]->code);
  3113. $errors = $result->errors->forKey('transaction')->forKey('descriptor')->onAttribute('phone');
  3114. $this->assertEquals(Braintree\Error\Codes::DESCRIPTOR_PHONE_FORMAT_IS_INVALID, $errors[0]->code);
  3115. $errors = $result->errors->forKey('transaction')->forKey('descriptor')->onAttribute('url');
  3116. $this->assertEquals(Braintree\Error\Codes::DESCRIPTOR_URL_FORMAT_IS_INVALID, $errors[0]->code);
  3117. }
  3118. public function testSale_withHoldInEscrow()
  3119. {
  3120. $result = Braintree\Transaction::sale([
  3121. 'merchantAccountId' => Test\Helper::nonDefaultSubMerchantAccountId(),
  3122. 'amount' => '100.00',
  3123. 'creditCard' => [
  3124. 'number' => '5105105105105100',
  3125. 'expirationDate' => '05/12'
  3126. ],
  3127. 'options' => [
  3128. 'holdInEscrow' => true
  3129. ],
  3130. 'serviceFeeAmount' => '1.00'
  3131. ]);
  3132. $this->assertTrue($result->success);
  3133. $transaction = $result->transaction;
  3134. $this->assertEquals(Braintree\Transaction::ESCROW_HOLD_PENDING, $transaction->escrowStatus);
  3135. }
  3136. public function testSale_withHoldInEscrowFailsForMasterMerchantAccount()
  3137. {
  3138. $result = Braintree\Transaction::sale([
  3139. 'merchantAccountId' => Test\Helper::nonDefaultMerchantAccountId(),
  3140. 'amount' => '100.00',
  3141. 'creditCard' => [
  3142. 'number' => '5105105105105100',
  3143. 'expirationDate' => '05/12'
  3144. ],
  3145. 'options' => [
  3146. 'holdInEscrow' => true
  3147. ]
  3148. ]);
  3149. $this->assertFalse($result->success);
  3150. $errors = $result->errors->forKey('transaction')->onAttribute('base');
  3151. $this->assertEquals(
  3152. Braintree\Error\Codes::TRANSACTION_CANNOT_HOLD_IN_ESCROW,
  3153. $errors[0]->code
  3154. );
  3155. }
  3156. public function testSale_withThreeDSecureOptionRequired()
  3157. {
  3158. $http = new HttpClientApi(Braintree\Configuration::$global);
  3159. $nonce = $http->nonce_for_new_card([
  3160. "creditCard" => [
  3161. "number" => "4111111111111111",
  3162. "expirationMonth" => "11",
  3163. "expirationYear" => "2099"
  3164. ]
  3165. ]);
  3166. $result = Braintree\Transaction::sale([
  3167. 'merchantAccountId' => Test\Helper::threeDSecureMerchantAccountId(),
  3168. 'amount' => '100.00',
  3169. 'creditCard' => [
  3170. 'number' => '4111111111111111',
  3171. 'expirationDate' => '05/09'
  3172. ],
  3173. 'options' => [
  3174. 'threeDSecure' => [
  3175. 'required' => true
  3176. ]
  3177. ]
  3178. ]);
  3179. $this->assertFalse($result->success);
  3180. $this->assertEquals(Braintree\Transaction::THREE_D_SECURE, $result->transaction->gatewayRejectionReason);
  3181. }
  3182. public function testSale_withThreeDSecureOptionRequiredInSnakeCase()
  3183. {
  3184. $http = new HttpClientApi(Braintree\Configuration::$global);
  3185. $nonce = $http->nonce_for_new_card([
  3186. "creditCard" => [
  3187. "number" => "4111111111111111",
  3188. "expirationMonth" => "11",
  3189. "expirationYear" => "2099"
  3190. ]
  3191. ]);
  3192. $result = Braintree\Transaction::sale([
  3193. 'merchantAccountId' => Test\Helper::threeDSecureMerchantAccountId(),
  3194. 'amount' => '100.00',
  3195. 'creditCard' => [
  3196. 'number' => '4111111111111111',
  3197. 'expirationDate' => '05/09'
  3198. ],
  3199. 'options' => [
  3200. 'three_d_secure' => [
  3201. 'required' => true
  3202. ]
  3203. ]
  3204. ]);
  3205. $this->assertFalse($result->success);
  3206. $this->assertEquals(Braintree\Transaction::THREE_D_SECURE, $result->transaction->gatewayRejectionReason);
  3207. }
  3208. public function testSale_withThreeDSecureToken()
  3209. {
  3210. $threeDSecureToken = Test\Helper::create3DSVerification(
  3211. Test\Helper::threeDSecureMerchantAccountId(),
  3212. [
  3213. 'number' => '4111111111111111',
  3214. 'expirationMonth' => '05',
  3215. 'expirationYear' => '2009'
  3216. ]
  3217. );
  3218. $result = Braintree\Transaction::sale([
  3219. 'merchantAccountId' => Test\Helper::threeDSecureMerchantAccountId(),
  3220. 'amount' => '100.00',
  3221. 'creditCard' => [
  3222. 'number' => '4111111111111111',
  3223. 'expirationDate' => '05/09'
  3224. ],
  3225. 'threeDSecureToken' => $threeDSecureToken
  3226. ]);
  3227. $this->assertTrue($result->success);
  3228. }
  3229. public function testSale_returnsErrorIfThreeDSecureToken()
  3230. {
  3231. $result = Braintree\Transaction::sale([
  3232. 'merchantAccountId' => Test\Helper::threeDSecureMerchantAccountId(),
  3233. 'amount' => '100.00',
  3234. 'creditCard' => [
  3235. 'number' => '4111111111111111',
  3236. 'expirationDate' => '05/09'
  3237. ],
  3238. 'threeDSecureToken' => NULL
  3239. ]);
  3240. $this->assertFalse($result->success);
  3241. $errors = $result->errors->forKey('transaction')->onAttribute('threeDSecureToken');
  3242. $this->assertEquals(
  3243. Braintree\Error\Codes::TRANSACTION_THREE_D_SECURE_TOKEN_IS_INVALID,
  3244. $errors[0]->code
  3245. );
  3246. }
  3247. public function testSale_returnsErrorIf3dsLookupDataDoesNotMatchTransactionData()
  3248. {
  3249. $threeDSecureToken = Test\Helper::create3DSVerification(
  3250. Test\Helper::threeDSecureMerchantAccountId(),
  3251. [
  3252. 'number' => '4111111111111111',
  3253. 'expirationMonth' => '05',
  3254. 'expirationYear' => '2009'
  3255. ]
  3256. );
  3257. $result = Braintree\Transaction::sale([
  3258. 'merchantAccountId' => Test\Helper::threeDSecureMerchantAccountId(),
  3259. 'amount' => '100.00',
  3260. 'creditCard' => [
  3261. 'number' => '5105105105105100',
  3262. 'expirationDate' => '05/09'
  3263. ],
  3264. 'threeDSecureToken' => $threeDSecureToken
  3265. ]);
  3266. $this->assertFalse($result->success);
  3267. $errors = $result->errors->forKey('transaction')->onAttribute('threeDSecureToken');
  3268. $this->assertEquals(
  3269. Braintree\Error\Codes::TRANSACTION_THREE_D_SECURE_TRANSACTION_DATA_DOESNT_MATCH_VERIFY,
  3270. $errors[0]->code
  3271. );
  3272. }
  3273. public function testSale_withThreeDSecurePassThru()
  3274. {
  3275. $result = Braintree\Transaction::sale([
  3276. 'merchantAccountId' => Test\Helper::threeDSecureMerchantAccountId(),
  3277. 'amount' => '100.00',
  3278. 'creditCard' => [
  3279. 'number' => '5105105105105100',
  3280. 'expirationDate' => '05/09'
  3281. ],
  3282. 'threeDSecurePassThru' => [
  3283. 'eciFlag' => '02',
  3284. 'cavv' => 'some_cavv',
  3285. 'xid' => 'some_xid'
  3286. ],
  3287. ]);
  3288. $this->assertTrue($result->success);
  3289. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $result->transaction->status);
  3290. }
  3291. public function testSale_returnsErrorsWhenThreeDSecurePassThruMerchantAcountDoesNotSupportCardType()
  3292. {
  3293. $result = Braintree\Transaction::sale([
  3294. 'merchantAccountId' => 'adyen_ma',
  3295. 'amount' => '100.00',
  3296. 'creditCard' => [
  3297. 'number' => '5105105105105100',
  3298. 'expirationDate' => '05/09'
  3299. ],
  3300. 'threeDSecurePassThru' => [
  3301. 'eciFlag' => '02',
  3302. 'cavv' => 'some_cavv',
  3303. 'xid' => 'some_xid'
  3304. ],
  3305. ]);
  3306. $this->assertFalse($result->success);
  3307. $errors = $result->errors->forKey('transaction');
  3308. $this->assertEquals(
  3309. Braintree\Error\Codes::TRANSACTION_THREE_D_SECURE_MERCHANT_ACCOUNT_DOES_NOT_SUPPORT_CARD_TYPE,
  3310. $errors->onAttribute("merchantAccountId")[0]->code
  3311. );
  3312. }
  3313. public function testSale_returnsErrorsWhenThreeDSecurePassThruIsMissingEciFlag()
  3314. {
  3315. $result = Braintree\Transaction::sale([
  3316. 'merchantAccountId' => Test\Helper::threeDSecureMerchantAccountId(),
  3317. 'amount' => '100.00',
  3318. 'creditCard' => [
  3319. 'number' => '5105105105105100',
  3320. 'expirationDate' => '05/09'
  3321. ],
  3322. 'threeDSecurePassThru' => [
  3323. 'eciFlag' => '',
  3324. 'cavv' => 'some_cavv',
  3325. 'xid' => 'some_xid'
  3326. ],
  3327. ]);
  3328. $this->assertFalse($result->success);
  3329. $errors = $result->errors->forKey('transaction')->forKey('threeDSecurePassThru');
  3330. $this->assertEquals(
  3331. Braintree\Error\Codes::TRANSACTION_THREE_D_SECURE_ECI_FLAG_IS_REQUIRED,
  3332. $errors->onAttribute("eciFlag")[0]->code
  3333. );
  3334. }
  3335. public function testSale_returnsErrorsWhenThreeDSecurePassThruIsMissingCavvOrXid()
  3336. {
  3337. $result = Braintree\Transaction::sale([
  3338. 'merchantAccountId' => Test\Helper::threeDSecureMerchantAccountId(),
  3339. 'amount' => '100.00',
  3340. 'creditCard' => [
  3341. 'number' => '5105105105105100',
  3342. 'expirationDate' => '05/09'
  3343. ],
  3344. 'threeDSecurePassThru' => [
  3345. 'eciFlag' => '06',
  3346. 'cavv' => '',
  3347. 'xid' => ''
  3348. ],
  3349. ]);
  3350. $this->assertFalse($result->success);
  3351. $errors = $result->errors->forKey('transaction')->forKey('threeDSecurePassThru');
  3352. $this->assertEquals(
  3353. Braintree\Error\Codes::TRANSACTION_THREE_D_SECURE_CAVV_IS_REQUIRED,
  3354. $errors->onAttribute("cavv")[0]->code
  3355. );
  3356. }
  3357. public function testSale_returnsErrorsWhenThreeDSecurePassThruEciFlagIsInvalid()
  3358. {
  3359. $result = Braintree\Transaction::sale([
  3360. 'merchantAccountId' => Test\Helper::threeDSecureMerchantAccountId(),
  3361. 'amount' => '100.00',
  3362. 'creditCard' => [
  3363. 'number' => '5105105105105100',
  3364. 'expirationDate' => '05/09'
  3365. ],
  3366. 'threeDSecurePassThru' => [
  3367. 'eciFlag' => 'bad_eci_flag',
  3368. 'cavv' => 'some_cavv',
  3369. 'xid' => 'some_xid'
  3370. ],
  3371. ]);
  3372. $this->assertFalse($result->success);
  3373. $errors = $result->errors->forKey('transaction')->forKey('threeDSecurePassThru');
  3374. $this->assertEquals(
  3375. Braintree\Error\Codes::TRANSACTION_THREE_D_SECURE_ECI_FLAG_IS_INVALID,
  3376. $errors->onAttribute("eciFlag")[0]->code
  3377. );
  3378. }
  3379. public function testHoldInEscrow_afterSale()
  3380. {
  3381. $result = Braintree\Transaction::sale([
  3382. 'merchantAccountId' => Test\Helper::nonDefaultSubMerchantAccountId(),
  3383. 'amount' => '100.00',
  3384. 'creditCard' => [
  3385. 'number' => '5105105105105100',
  3386. 'expirationDate' => '05/12'
  3387. ],
  3388. 'serviceFeeAmount' => '1.00'
  3389. ]);
  3390. $result = Braintree\Transaction::holdInEscrow($result->transaction->id);
  3391. $this->assertTrue($result->success);
  3392. $this->assertEquals(Braintree\Transaction::ESCROW_HOLD_PENDING, $result->transaction->escrowStatus);
  3393. }
  3394. public function testHoldInEscrow_afterSaleFailsWithMasterMerchantAccount()
  3395. {
  3396. $result = Braintree\Transaction::sale([
  3397. 'merchantAccountId' => Test\Helper::nonDefaultMerchantAccountId(),
  3398. 'amount' => '100.00',
  3399. 'creditCard' => [
  3400. 'number' => '5105105105105100',
  3401. 'expirationDate' => '05/12'
  3402. ]
  3403. ]);
  3404. $result = Braintree\Transaction::holdInEscrow($result->transaction->id);
  3405. $this->assertFalse($result->success);
  3406. $errors = $result->errors->forKey('transaction')->onAttribute('base');
  3407. $this->assertEquals(
  3408. Braintree\Error\Codes::TRANSACTION_CANNOT_HOLD_IN_ESCROW,
  3409. $errors[0]->code
  3410. );
  3411. }
  3412. public function testSubmitForRelease_FromEscrow()
  3413. {
  3414. $transaction = $this->createEscrowedTransaction();
  3415. $result = Braintree\Transaction::releaseFromEscrow($transaction->id);
  3416. $this->assertTrue($result->success);
  3417. $this->assertEquals(Braintree\Transaction::ESCROW_RELEASE_PENDING, $result->transaction->escrowStatus);
  3418. }
  3419. public function testSubmitForRelease_fromEscrowFailsForTransactionsNotHeldInEscrow()
  3420. {
  3421. $result = Braintree\Transaction::sale([
  3422. 'merchantAccountId' => Test\Helper::nonDefaultMerchantAccountId(),
  3423. 'amount' => '100.00',
  3424. 'creditCard' => [
  3425. 'number' => '5105105105105100',
  3426. 'expirationDate' => '05/12'
  3427. ]
  3428. ]);
  3429. $result = Braintree\Transaction::releaseFromEscrow($result->transaction->id);
  3430. $this->assertFalse($result->success);
  3431. $errors = $result->errors->forKey('transaction')->onAttribute('base');
  3432. $this->assertEquals(
  3433. Braintree\Error\Codes::TRANSACTION_CANNOT_RELEASE_FROM_ESCROW,
  3434. $errors[0]->code
  3435. );
  3436. }
  3437. public function testCancelRelease_fromEscrow()
  3438. {
  3439. $transaction = $this->createEscrowedTransaction();
  3440. $result = Braintree\Transaction::releaseFromEscrow($transaction->id);
  3441. $result = Braintree\Transaction::cancelRelease($transaction->id);
  3442. $this->assertTrue($result->success);
  3443. $this->assertEquals(
  3444. Braintree\Transaction::ESCROW_HELD,
  3445. $result->transaction->escrowStatus
  3446. );
  3447. }
  3448. public function testCancelRelease_fromEscrowFailsIfTransactionNotSubmittedForRelease()
  3449. {
  3450. $transaction = $this->createEscrowedTransaction();
  3451. $result = Braintree\Transaction::cancelRelease($transaction->id);
  3452. $this->assertFalse($result->success);
  3453. $errors = $result->errors->forKey('transaction')->onAttribute('base');
  3454. $this->assertEquals(
  3455. Braintree\Error\Codes::TRANSACTION_CANNOT_CANCEL_RELEASE,
  3456. $errors[0]->code
  3457. );
  3458. }
  3459. public function testCreateFromTransparentRedirect()
  3460. {
  3461. Test\Helper::suppressDeprecationWarnings();
  3462. $queryString = $this->createTransactionViaTr(
  3463. [
  3464. 'transaction' => [
  3465. 'customer' => [
  3466. 'first_name' => 'First'
  3467. ],
  3468. 'credit_card' => [
  3469. 'number' => '5105105105105100',
  3470. 'expiration_date' => '05/12'
  3471. ]
  3472. ]
  3473. ],
  3474. [
  3475. 'transaction' => [
  3476. 'type' => Braintree\Transaction::SALE,
  3477. 'amount' => '100.00'
  3478. ]
  3479. ]
  3480. );
  3481. $result = Braintree\Transaction::createFromTransparentRedirect($queryString);
  3482. Test\Helper::assertPrintable($result);
  3483. $this->assertTrue($result->success);
  3484. $this->assertEquals('100.00', $result->transaction->amount);
  3485. $this->assertEquals(Braintree\Transaction::SALE, $result->transaction->type);
  3486. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $result->transaction->status);
  3487. $creditCard = $result->transaction->creditCardDetails;
  3488. $this->assertEquals('510510', $creditCard->bin);
  3489. $this->assertEquals('5100', $creditCard->last4);
  3490. $this->assertEquals('US', $creditCard->customerLocation);
  3491. $this->assertEquals('MasterCard', $creditCard->cardType);
  3492. $this->assertEquals('05/2012', $creditCard->expirationDate);
  3493. $this->assertEquals('510510******5100', $creditCard->maskedNumber);
  3494. $customer = $result->transaction->customerDetails;
  3495. $this->assertequals('First', $customer->firstName);
  3496. }
  3497. public function testCreateFromTransparentRedirectWithInvalidParams()
  3498. {
  3499. Test\Helper::suppressDeprecationWarnings();
  3500. $queryString = $this->createTransactionViaTr(
  3501. [
  3502. 'transaction' => [
  3503. 'bad_key' => 'bad_value',
  3504. 'customer' => [
  3505. 'first_name' => 'First'
  3506. ],
  3507. 'credit_card' => [
  3508. 'number' => '5105105105105100',
  3509. 'expiration_date' => '05/12'
  3510. ]
  3511. ]
  3512. ],
  3513. [
  3514. 'transaction' => [
  3515. 'type' => Braintree\Transaction::SALE,
  3516. 'amount' => '100.00'
  3517. ]
  3518. ]
  3519. );
  3520. try {
  3521. $result = Braintree\Transaction::createFromTransparentRedirect($queryString);
  3522. $this->fail();
  3523. } catch (Braintree\Exception\Authorization $e) {
  3524. $this->assertEquals("Invalid params: transaction[bad_key]", $e->getMessage());
  3525. }
  3526. }
  3527. public function testCreateFromTransparentRedirect_withParamsInTrData()
  3528. {
  3529. Test\Helper::suppressDeprecationWarnings();
  3530. $queryString = $this->createTransactionViaTr(
  3531. [
  3532. ],
  3533. [
  3534. 'transaction' => [
  3535. 'type' => Braintree\Transaction::SALE,
  3536. 'amount' => '100.00',
  3537. 'customer' => [
  3538. 'firstName' => 'First'
  3539. ],
  3540. 'creditCard' => [
  3541. 'number' => '5105105105105100',
  3542. 'expirationDate' => '05/12'
  3543. ]
  3544. ]
  3545. ]
  3546. );
  3547. $result = Braintree\Transaction::createFromTransparentRedirect($queryString);
  3548. $this->assertTrue($result->success);
  3549. $this->assertEquals('100.00', $result->transaction->amount);
  3550. $this->assertEquals(Braintree\Transaction::SALE, $result->transaction->type);
  3551. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $result->transaction->status);
  3552. $creditCard = $result->transaction->creditCardDetails;
  3553. $this->assertEquals('510510', $creditCard->bin);
  3554. $this->assertEquals('5100', $creditCard->last4);
  3555. $this->assertEquals('US', $creditCard->customerLocation);
  3556. $this->assertEquals('MasterCard', $creditCard->cardType);
  3557. $this->assertEquals('05/2012', $creditCard->expirationDate);
  3558. $this->assertEquals('510510******5100', $creditCard->maskedNumber);
  3559. $customer = $result->transaction->customerDetails;
  3560. $this->assertequals('First', $customer->firstName);
  3561. }
  3562. public function testCreateFromTransparentRedirect_withValidationErrors()
  3563. {
  3564. Test\Helper::suppressDeprecationWarnings();
  3565. $queryString = $this->createTransactionViaTr(
  3566. [
  3567. 'transaction' => [
  3568. 'customer' => [
  3569. 'first_name' => str_repeat('x', 256),
  3570. ],
  3571. 'credit_card' => [
  3572. 'number' => 'invalid',
  3573. 'expiration_date' => ''
  3574. ]
  3575. ]
  3576. ],
  3577. [
  3578. 'transaction' => ['type' => Braintree\Transaction::SALE]
  3579. ]
  3580. );
  3581. $result = Braintree\Transaction::createFromTransparentRedirect($queryString);
  3582. $this->assertFalse($result->success);
  3583. $errors = $result->errors->forKey('transaction')->forKey('customer')->onAttribute('firstName');
  3584. $this->assertEquals(Braintree\Error\Codes::CUSTOMER_FIRST_NAME_IS_TOO_LONG, $errors[0]->code);
  3585. $errors = $result->errors->forKey('transaction')->forKey('creditCard')->onAttribute('number');
  3586. $this->assertTrue(count($errors) > 0);
  3587. $errors = $result->errors->forKey('transaction')->forKey('creditCard')->onAttribute('expirationDate');
  3588. $this->assertEquals(Braintree\Error\Codes::CREDIT_CARD_EXPIRATION_DATE_IS_REQUIRED, $errors[0]->code);
  3589. }
  3590. public function testRefund()
  3591. {
  3592. $transaction = $this->createTransactionToRefund();
  3593. $result = Braintree\Transaction::refund($transaction->id);
  3594. $this->assertTrue($result->success);
  3595. $refund = $result->transaction;
  3596. $this->assertEquals(Braintree\Transaction::CREDIT, $refund->type);
  3597. $this->assertEquals($transaction->id, $refund->refundedTransactionId);
  3598. $this->assertEquals($refund->id, Braintree\Transaction::find($transaction->id)->refundId);
  3599. }
  3600. public function testRefundWithPartialAmount()
  3601. {
  3602. $transaction = $this->createTransactionToRefund();
  3603. $result = Braintree\Transaction::refund($transaction->id, '50.00');
  3604. $this->assertTrue($result->success);
  3605. $this->assertEquals(Braintree\Transaction::CREDIT, $result->transaction->type);
  3606. $this->assertEquals("50.00", $result->transaction->amount);
  3607. }
  3608. public function testMultipleRefundsWithPartialAmounts()
  3609. {
  3610. $transaction = $this->createTransactionToRefund();
  3611. $transaction1 = Braintree\Transaction::refund($transaction->id, '50.00')->transaction;
  3612. $this->assertEquals(Braintree\Transaction::CREDIT, $transaction1->type);
  3613. $this->assertEquals("50.00", $transaction1->amount);
  3614. $transaction2 = Braintree\Transaction::refund($transaction->id, '50.00')->transaction;
  3615. $this->assertEquals(Braintree\Transaction::CREDIT, $transaction2->type);
  3616. $this->assertEquals("50.00", $transaction2->amount);
  3617. $transaction = Braintree\Transaction::find($transaction->id);
  3618. $expectedRefundIds = [$transaction1->id, $transaction2->id];
  3619. $refundIds = $transaction->refundIds;
  3620. sort($expectedRefundIds);
  3621. sort($refundIds);
  3622. $this->assertEquals($expectedRefundIds, $refundIds);
  3623. }
  3624. public function testRefundWithUnsuccessfulPartialAmount()
  3625. {
  3626. $transaction = $this->createTransactionToRefund();
  3627. $result = Braintree\Transaction::refund($transaction->id, '150.00');
  3628. $this->assertFalse($result->success);
  3629. $errors = $result->errors->forKey('transaction')->onAttribute('amount');
  3630. $this->assertEquals(
  3631. Braintree\Error\Codes::TRANSACTION_REFUND_AMOUNT_IS_TOO_LARGE,
  3632. $errors[0]->code
  3633. );
  3634. }
  3635. public function testRefundWithOptionsParam()
  3636. {
  3637. $transaction = $this->createTransactionToRefund();
  3638. $options = [
  3639. "orderId" => 'abcd',
  3640. "amount" => '1.00'
  3641. ];
  3642. $result = Braintree\Transaction::refund($transaction->id, $options);
  3643. $this->assertTrue($result->success);
  3644. $this->assertEquals(
  3645. 'abcd',
  3646. $result->transaction->orderId
  3647. );
  3648. $this->assertEquals(
  3649. '1.00',
  3650. $result->transaction->amount
  3651. );
  3652. }
  3653. public function testGatewayRejectionOnApplicationIncomplete()
  3654. {
  3655. $gateway = new Braintree\Gateway([
  3656. 'clientId' => 'client_id$development$integration_client_id',
  3657. 'clientSecret' => 'client_secret$development$integration_client_secret'
  3658. ]);
  3659. $result = $gateway->merchant()->create([
  3660. 'email' => 'name@email.com',
  3661. 'countryCodeAlpha3' => 'USA',
  3662. 'paymentMethods' => ['credit_card', 'paypal']
  3663. ]);
  3664. $gateway = new Braintree\Gateway([
  3665. 'accessToken' => $result->credentials->accessToken,
  3666. ]);
  3667. $result = $gateway->transaction()->sale([
  3668. 'amount' => '4000.00',
  3669. 'creditCard' => [
  3670. 'number' => '4111111111111111',
  3671. 'expirationDate' => '05/20'
  3672. ]
  3673. ]);
  3674. $this->assertFalse($result->success);
  3675. $transaction = $result->transaction;
  3676. $this->assertEquals(Braintree\Transaction::APPLICATION_INCOMPLETE, $transaction->gatewayRejectionReason);
  3677. }
  3678. public function testGatewayRejectionOnAvs()
  3679. {
  3680. $old_merchant_id = Braintree\Configuration::merchantId();
  3681. $old_public_key = Braintree\Configuration::publicKey();
  3682. $old_private_key = Braintree\Configuration::privateKey();
  3683. Braintree\Configuration::merchantId('processing_rules_merchant_id');
  3684. Braintree\Configuration::publicKey('processing_rules_public_key');
  3685. Braintree\Configuration::privateKey('processing_rules_private_key');
  3686. $result = Braintree\Transaction::sale([
  3687. 'amount' => '100.00',
  3688. 'billing' => [
  3689. 'streetAddress' => '200 2nd Street'
  3690. ],
  3691. 'creditCard' => [
  3692. 'number' => '5105105105105100',
  3693. 'expirationDate' => '05/12'
  3694. ]
  3695. ]);
  3696. Braintree\Configuration::merchantId($old_merchant_id);
  3697. Braintree\Configuration::publicKey($old_public_key);
  3698. Braintree\Configuration::privateKey($old_private_key);
  3699. $this->assertFalse($result->success);
  3700. Test\Helper::assertPrintable($result);
  3701. $transaction = $result->transaction;
  3702. $this->assertEquals(Braintree\Transaction::AVS, $transaction->gatewayRejectionReason);
  3703. }
  3704. public function testGatewayRejectionOnAvsAndCvv()
  3705. {
  3706. $old_merchant_id = Braintree\Configuration::merchantId();
  3707. $old_public_key = Braintree\Configuration::publicKey();
  3708. $old_private_key = Braintree\Configuration::privateKey();
  3709. Braintree\Configuration::merchantId('processing_rules_merchant_id');
  3710. Braintree\Configuration::publicKey('processing_rules_public_key');
  3711. Braintree\Configuration::privateKey('processing_rules_private_key');
  3712. $result = Braintree\Transaction::sale([
  3713. 'amount' => '100.00',
  3714. 'billing' => [
  3715. 'postalCode' => '20000'
  3716. ],
  3717. 'creditCard' => [
  3718. 'number' => '5105105105105100',
  3719. 'expirationDate' => '05/12',
  3720. 'cvv' => '200'
  3721. ]
  3722. ]);
  3723. Braintree\Configuration::merchantId($old_merchant_id);
  3724. Braintree\Configuration::publicKey($old_public_key);
  3725. Braintree\Configuration::privateKey($old_private_key);
  3726. $this->assertFalse($result->success);
  3727. $transaction = $result->transaction;
  3728. $this->assertEquals(Braintree\Transaction::AVS_AND_CVV, $transaction->gatewayRejectionReason);
  3729. }
  3730. public function testGatewayRejectionOnCvv()
  3731. {
  3732. $old_merchant_id = Braintree\Configuration::merchantId();
  3733. $old_public_key = Braintree\Configuration::publicKey();
  3734. $old_private_key = Braintree\Configuration::privateKey();
  3735. Braintree\Configuration::merchantId('processing_rules_merchant_id');
  3736. Braintree\Configuration::publicKey('processing_rules_public_key');
  3737. Braintree\Configuration::privateKey('processing_rules_private_key');
  3738. $result = Braintree\Transaction::sale([
  3739. 'amount' => '100.00',
  3740. 'creditCard' => [
  3741. 'number' => '5105105105105100',
  3742. 'expirationDate' => '05/12',
  3743. 'cvv' => '200'
  3744. ]
  3745. ]);
  3746. Braintree\Configuration::merchantId($old_merchant_id);
  3747. Braintree\Configuration::publicKey($old_public_key);
  3748. Braintree\Configuration::privateKey($old_private_key);
  3749. $this->assertFalse($result->success);
  3750. $transaction = $result->transaction;
  3751. $this->assertEquals(Braintree\Transaction::CVV, $transaction->gatewayRejectionReason);
  3752. }
  3753. public function testGatewayRejectionOnFraud()
  3754. {
  3755. $result = Braintree\Transaction::sale([
  3756. 'amount' => '100.00',
  3757. 'creditCard' => [
  3758. 'number' => '4000111111111511',
  3759. 'expirationDate' => '05/17',
  3760. 'cvv' => '333'
  3761. ]
  3762. ]);
  3763. $this->assertFalse($result->success);
  3764. $this->assertEquals(Braintree\Transaction::FRAUD, $result->transaction->gatewayRejectionReason);
  3765. }
  3766. public function testSnapshotPlanIdAddOnsAndDiscountsFromSubscription()
  3767. {
  3768. $creditCard = SubscriptionHelper::createCreditCard();
  3769. $plan = SubscriptionHelper::triallessPlan();
  3770. $result = Braintree\Subscription::create([
  3771. 'paymentMethodToken' => $creditCard->token,
  3772. 'planId' => $plan['id'],
  3773. 'addOns' => [
  3774. 'add' => [
  3775. [
  3776. 'amount' => '11.00',
  3777. 'inheritedFromId' => 'increase_10',
  3778. 'quantity' => 2,
  3779. 'numberOfBillingCycles' => 5
  3780. ],
  3781. [
  3782. 'amount' => '21.00',
  3783. 'inheritedFromId' => 'increase_20',
  3784. 'quantity' => 3,
  3785. 'numberOfBillingCycles' => 6
  3786. ]
  3787. ],
  3788. ],
  3789. 'discounts' => [
  3790. 'add' => [
  3791. [
  3792. 'amount' => '7.50',
  3793. 'inheritedFromId' => 'discount_7',
  3794. 'quantity' => 2,
  3795. 'neverExpires' => true
  3796. ]
  3797. ]
  3798. ]
  3799. ]);
  3800. $transaction = $result->subscription->transactions[0];
  3801. $this->assertEquals($transaction->planId, $plan['id']);
  3802. $addOns = $transaction->addOns;
  3803. SubscriptionHelper::sortModificationsById($addOns);
  3804. $this->assertEquals($addOns[0]->amount, "11.00");
  3805. $this->assertEquals($addOns[0]->id, "increase_10");
  3806. $this->assertEquals($addOns[0]->quantity, 2);
  3807. $this->assertEquals($addOns[0]->numberOfBillingCycles, 5);
  3808. $this->assertFalse($addOns[0]->neverExpires);
  3809. $this->assertEquals($addOns[1]->amount, "21.00");
  3810. $this->assertEquals($addOns[1]->id, "increase_20");
  3811. $this->assertEquals($addOns[1]->quantity, 3);
  3812. $this->assertEquals($addOns[1]->numberOfBillingCycles, 6);
  3813. $this->assertFalse($addOns[1]->neverExpires);
  3814. $discounts = $transaction->discounts;
  3815. $this->assertEquals($discounts[0]->amount, "7.50");
  3816. $this->assertEquals($discounts[0]->id, "discount_7");
  3817. $this->assertEquals($discounts[0]->quantity, 2);
  3818. $this->assertEquals($discounts[0]->numberOfBillingCycles, null);
  3819. $this->assertTrue($discounts[0]->neverExpires);
  3820. }
  3821. public function createTransactionViaTr($regularParams, $trParams)
  3822. {
  3823. Test\Helper::suppressDeprecationWarnings();
  3824. $trData = Braintree\TransparentRedirect::transactionData(
  3825. array_merge($trParams, ["redirectUrl" => "http://www.example.com"])
  3826. );
  3827. return Test\Helper::submitTrRequest(
  3828. Braintree\Transaction::createTransactionUrl(),
  3829. $regularParams,
  3830. $trData
  3831. );
  3832. }
  3833. public function createTransactionToRefund()
  3834. {
  3835. $transaction = Braintree\Transaction::saleNoValidate([
  3836. 'amount' => '100.00',
  3837. 'creditCard' => [
  3838. 'number' => '5105105105105100',
  3839. 'expirationDate' => '05/12'
  3840. ],
  3841. 'options' => ['submitForSettlement' => true]
  3842. ]);
  3843. Braintree\Test\Transaction::settle($transaction->id);
  3844. return $transaction;
  3845. }
  3846. public function createEscrowedTransaction()
  3847. {
  3848. $result = Braintree\Transaction::sale([
  3849. 'merchantAccountId' => Test\Helper::nonDefaultSubMerchantAccountId(),
  3850. 'amount' => '100.00',
  3851. 'creditCard' => [
  3852. 'number' => '5105105105105100',
  3853. 'expirationDate' => '05/12'
  3854. ],
  3855. 'options' => [
  3856. 'holdInEscrow' => true
  3857. ],
  3858. 'serviceFeeAmount' => '1.00'
  3859. ]);
  3860. Test\Helper::escrow($result->transaction->id);
  3861. return $result->transaction;
  3862. }
  3863. public function testCardTypeIndicators()
  3864. {
  3865. $transaction = Braintree\Transaction::saleNoValidate([
  3866. 'amount' => '100.00',
  3867. 'creditCard' => [
  3868. 'number' => CardTypeIndicators::PREPAID,
  3869. 'expirationDate' => '05/12',
  3870. ]
  3871. ]);
  3872. $this->assertEquals(Braintree\CreditCard::PREPAID_YES, $transaction->creditCardDetails->prepaid);
  3873. $prepaid_card_transaction = Braintree\Transaction::saleNoValidate([
  3874. 'amount' => '100.00',
  3875. 'creditCard' => [
  3876. 'number' => CardTypeIndicators::COMMERCIAL,
  3877. 'expirationDate' => '05/12',
  3878. ]
  3879. ]);
  3880. $this->assertEquals(Braintree\CreditCard::COMMERCIAL_YES, $prepaid_card_transaction->creditCardDetails->commercial);
  3881. $transaction = Braintree\Transaction::saleNoValidate([
  3882. 'amount' => '100.00',
  3883. 'creditCard' => [
  3884. 'number' => CardTypeIndicators::PAYROLL,
  3885. 'expirationDate' => '05/12',
  3886. ]
  3887. ]);
  3888. $this->assertEquals(Braintree\CreditCard::PAYROLL_YES, $transaction->creditCardDetails->payroll);
  3889. $this->assertEquals("MSA", $transaction->creditCardDetails->productId);
  3890. $transaction = Braintree\Transaction::saleNoValidate([
  3891. 'amount' => '100.00',
  3892. 'creditCard' => [
  3893. 'number' => CardTypeIndicators::HEALTHCARE,
  3894. 'expirationDate' => '05/12',
  3895. ]
  3896. ]);
  3897. $this->assertEquals(Braintree\CreditCard::HEALTHCARE_YES, $transaction->creditCardDetails->healthcare);
  3898. $this->assertEquals("J3", $transaction->creditCardDetails->productId);
  3899. $transaction = Braintree\Transaction::saleNoValidate([
  3900. 'amount' => '100.00',
  3901. 'creditCard' => [
  3902. 'number' => CardTypeIndicators::DURBIN_REGULATED,
  3903. 'expirationDate' => '05/12',
  3904. ]
  3905. ]);
  3906. $this->assertEquals(Braintree\CreditCard::DURBIN_REGULATED_YES, $transaction->creditCardDetails->durbinRegulated);
  3907. $transaction = Braintree\Transaction::saleNoValidate([
  3908. 'amount' => '100.00',
  3909. 'creditCard' => [
  3910. 'number' => CardTypeIndicators::DEBIT,
  3911. 'expirationDate' => '05/12',
  3912. ]
  3913. ]);
  3914. $this->assertEquals(Braintree\CreditCard::DEBIT_YES, $transaction->creditCardDetails->debit);
  3915. $transaction = Braintree\Transaction::saleNoValidate([
  3916. 'amount' => '100.00',
  3917. 'creditCard' => [
  3918. 'number' => CardTypeIndicators::ISSUING_BANK,
  3919. 'expirationDate' => '05/12',
  3920. ]
  3921. ]);
  3922. $this->assertEquals("NETWORK ONLY", $transaction->creditCardDetails->issuingBank);
  3923. $transaction = Braintree\Transaction::saleNoValidate([
  3924. 'amount' => '100.00',
  3925. 'creditCard' => [
  3926. 'number' => CardTypeIndicators::COUNTRY_OF_ISSUANCE,
  3927. 'expirationDate' => '05/12',
  3928. ]
  3929. ]);
  3930. $this->assertEquals("USA", $transaction->creditCardDetails->countryOfIssuance);
  3931. }
  3932. public function testCreate_withVaultedPayPal()
  3933. {
  3934. $paymentMethodToken = 'PAYPAL_TOKEN-' . strval(rand());
  3935. $customer = Braintree\Customer::createNoValidate();
  3936. $http = new HttpClientApi(Braintree\Configuration::$global);
  3937. $nonce = $http->nonceForPayPalAccount([
  3938. 'paypal_account' => [
  3939. 'consent_code' => 'PAYPAL_CONSENT_CODE',
  3940. 'token' => $paymentMethodToken
  3941. ]
  3942. ]);
  3943. Braintree\PaymentMethod::create([
  3944. 'customerId' => $customer->id,
  3945. 'paymentMethodNonce' => $nonce
  3946. ]);
  3947. $result = Braintree\Transaction::sale([
  3948. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  3949. 'paymentMethodToken' => $paymentMethodToken,
  3950. ]);
  3951. $this->assertTrue($result->success);
  3952. $transaction = $result->transaction;
  3953. $this->assertEquals('payer@example.com', $transaction->paypalDetails->payerEmail);
  3954. $this->assertNotNull($transaction->paypalDetails->imageUrl);
  3955. $this->assertNotNull($transaction->paypalDetails->debugId);
  3956. }
  3957. public function testCreate_withFuturePayPal()
  3958. {
  3959. $paymentMethodToken = 'PAYPAL_TOKEN-' . strval(rand());
  3960. $http = new HttpClientApi(Braintree\Configuration::$global);
  3961. $nonce = $http->nonceForPayPalAccount([
  3962. 'paypal_account' => [
  3963. 'consent_code' => 'PAYPAL_CONSENT_CODE',
  3964. 'token' => $paymentMethodToken
  3965. ]
  3966. ]);
  3967. $result = Braintree\Transaction::sale([
  3968. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  3969. 'paymentMethodNonce' => $nonce,
  3970. ]);
  3971. $this->assertTrue($result->success);
  3972. $transaction = $result->transaction;
  3973. $this->assertEquals('payer@example.com', $transaction->paypalDetails->payerEmail);
  3974. $this->assertNotNull($transaction->paypalDetails->imageUrl);
  3975. $this->assertNotNull($transaction->paypalDetails->debugId);
  3976. $this->setExpectedException('Braintree\Exception\NotFound');
  3977. Braintree\PaymentMethod::find($paymentMethodToken);
  3978. }
  3979. public function testCreate_withPayeeId()
  3980. {
  3981. $paymentMethodToken = 'PAYPAL_TOKEN-' . strval(rand());
  3982. $http = new HttpClientApi(Braintree\Configuration::$global);
  3983. $nonce = $http->nonceForPayPalAccount([
  3984. 'paypal_account' => [
  3985. 'consent_code' => 'PAYPAL_CONSENT_CODE',
  3986. 'token' => $paymentMethodToken
  3987. ]
  3988. ]);
  3989. $result = Braintree\Transaction::sale([
  3990. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  3991. 'paymentMethodNonce' => $nonce,
  3992. 'paypalAccount' => [
  3993. 'payeeId' => 'fake-payee-id'
  3994. ]
  3995. ]);
  3996. $this->assertTrue($result->success);
  3997. $transaction = $result->transaction;
  3998. $this->assertEquals('payer@example.com', $transaction->paypalDetails->payerEmail);
  3999. $this->assertNotNull($transaction->paypalDetails->imageUrl);
  4000. $this->assertNotNull($transaction->paypalDetails->debugId);
  4001. $this->assertNotNull($transaction->paypalDetails->payeeId);
  4002. $this->setExpectedException('Braintree\Exception\NotFound');
  4003. Braintree\PaymentMethod::find($paymentMethodToken);
  4004. }
  4005. public function testCreate_withPayeeIdInOptions()
  4006. {
  4007. $paymentMethodToken = 'PAYPAL_TOKEN-' . strval(rand());
  4008. $http = new HttpClientApi(Braintree\Configuration::$global);
  4009. $nonce = $http->nonceForPayPalAccount([
  4010. 'paypal_account' => [
  4011. 'consent_code' => 'PAYPAL_CONSENT_CODE',
  4012. 'token' => $paymentMethodToken
  4013. ]
  4014. ]);
  4015. $result = Braintree\Transaction::sale([
  4016. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4017. 'paymentMethodNonce' => $nonce,
  4018. 'paypalAccount' => [],
  4019. 'options' => [
  4020. 'payeeId' => 'fake-payee-id'
  4021. ]
  4022. ]);
  4023. $this->assertTrue($result->success);
  4024. $transaction = $result->transaction;
  4025. $this->assertEquals('payer@example.com', $transaction->paypalDetails->payerEmail);
  4026. $this->assertNotNull($transaction->paypalDetails->imageUrl);
  4027. $this->assertNotNull($transaction->paypalDetails->debugId);
  4028. $this->assertNotNull($transaction->paypalDetails->payeeId);
  4029. $this->setExpectedException('Braintree\Exception\NotFound');
  4030. Braintree\PaymentMethod::find($paymentMethodToken);
  4031. }
  4032. public function testCreate_withPayeeIdInOptionsPayPal()
  4033. {
  4034. $paymentMethodToken = 'PAYPAL_TOKEN-' . strval(rand());
  4035. $http = new HttpClientApi(Braintree\Configuration::$global);
  4036. $nonce = $http->nonceForPayPalAccount([
  4037. 'paypal_account' => [
  4038. 'consent_code' => 'PAYPAL_CONSENT_CODE',
  4039. 'token' => $paymentMethodToken
  4040. ]
  4041. ]);
  4042. $result = Braintree\Transaction::sale([
  4043. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4044. 'paymentMethodNonce' => $nonce,
  4045. 'paypalAccount' => [],
  4046. 'options' => [
  4047. 'paypal' => [
  4048. 'payeeId' => 'fake-payee-id'
  4049. ]
  4050. ]
  4051. ]);
  4052. $this->assertTrue($result->success);
  4053. $transaction = $result->transaction;
  4054. $this->assertEquals('payer@example.com', $transaction->paypalDetails->payerEmail);
  4055. $this->assertNotNull($transaction->paypalDetails->imageUrl);
  4056. $this->assertNotNull($transaction->paypalDetails->debugId);
  4057. $this->assertNotNull($transaction->paypalDetails->payeeId);
  4058. $this->setExpectedException('Braintree\Exception\NotFound');
  4059. Braintree\PaymentMethod::find($paymentMethodToken);
  4060. }
  4061. public function testCreate_withPayeeEmail()
  4062. {
  4063. $paymentMethodToken = 'PAYPAL_TOKEN-' . strval(rand());
  4064. $http = new HttpClientApi(Braintree\Configuration::$global);
  4065. $nonce = $http->nonceForPayPalAccount([
  4066. 'paypal_account' => [
  4067. 'consent_code' => 'PAYPAL_CONSENT_CODE',
  4068. 'token' => $paymentMethodToken
  4069. ]
  4070. ]);
  4071. $result = Braintree\Transaction::sale([
  4072. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4073. 'paymentMethodNonce' => $nonce,
  4074. 'paypalAccount' => [
  4075. 'payeeEmail' => 'payee@example.com'
  4076. ]
  4077. ]);
  4078. $this->assertTrue($result->success);
  4079. $transaction = $result->transaction;
  4080. $this->assertEquals('payer@example.com', $transaction->paypalDetails->payerEmail);
  4081. $this->assertNotNull($transaction->paypalDetails->imageUrl);
  4082. $this->assertNotNull($transaction->paypalDetails->debugId);
  4083. $this->assertNotNull($transaction->paypalDetails->payeeEmail);
  4084. $this->setExpectedException('Braintree\Exception\NotFound');
  4085. Braintree\PaymentMethod::find($paymentMethodToken);
  4086. }
  4087. public function testCreate_withPayeeEmailInOptions()
  4088. {
  4089. $paymentMethodToken = 'PAYPAL_TOKEN-' . strval(rand());
  4090. $http = new HttpClientApi(Braintree\Configuration::$global);
  4091. $nonce = $http->nonceForPayPalAccount([
  4092. 'paypal_account' => [
  4093. 'consent_code' => 'PAYPAL_CONSENT_CODE',
  4094. 'token' => $paymentMethodToken
  4095. ]
  4096. ]);
  4097. $result = Braintree\Transaction::sale([
  4098. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4099. 'paymentMethodNonce' => $nonce,
  4100. 'paypalAccount' => [],
  4101. 'options' => [
  4102. 'payeeEmail' => 'payee@example.com'
  4103. ]
  4104. ]);
  4105. $this->assertTrue($result->success);
  4106. $transaction = $result->transaction;
  4107. $this->assertEquals('payer@example.com', $transaction->paypalDetails->payerEmail);
  4108. $this->assertNotNull($transaction->paypalDetails->imageUrl);
  4109. $this->assertNotNull($transaction->paypalDetails->debugId);
  4110. $this->assertNotNull($transaction->paypalDetails->payeeEmail);
  4111. $this->setExpectedException('Braintree\Exception\NotFound');
  4112. Braintree\PaymentMethod::find($paymentMethodToken);
  4113. }
  4114. public function testCreate_withPayeeEmailInOptionsPayPal()
  4115. {
  4116. $paymentMethodToken = 'PAYPAL_TOKEN-' . strval(rand());
  4117. $http = new HttpClientApi(Braintree\Configuration::$global);
  4118. $nonce = $http->nonceForPayPalAccount([
  4119. 'paypal_account' => [
  4120. 'consent_code' => 'PAYPAL_CONSENT_CODE',
  4121. 'token' => $paymentMethodToken
  4122. ]
  4123. ]);
  4124. $result = Braintree\Transaction::sale([
  4125. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4126. 'paymentMethodNonce' => $nonce,
  4127. 'paypalAccount' => [],
  4128. 'options' => [
  4129. 'paypal' => [
  4130. 'payeeEmail' => 'payee@example.com'
  4131. ]
  4132. ]
  4133. ]);
  4134. $this->assertTrue($result->success);
  4135. $transaction = $result->transaction;
  4136. $this->assertEquals('payer@example.com', $transaction->paypalDetails->payerEmail);
  4137. $this->assertNotNull($transaction->paypalDetails->imageUrl);
  4138. $this->assertNotNull($transaction->paypalDetails->debugId);
  4139. $this->assertNotNull($transaction->paypalDetails->payeeEmail);
  4140. $this->setExpectedException('Braintree\Exception\NotFound');
  4141. Braintree\PaymentMethod::find($paymentMethodToken);
  4142. }
  4143. public function testCreate_withPayPalCustomField()
  4144. {
  4145. $paymentMethodToken = 'PAYPAL_TOKEN-' . strval(rand());
  4146. $http = new HttpClientApi(Braintree\Configuration::$global);
  4147. $nonce = $http->nonceForPayPalAccount([
  4148. 'paypal_account' => [
  4149. 'consent_code' => 'PAYPAL_CONSENT_CODE',
  4150. 'token' => $paymentMethodToken
  4151. ]
  4152. ]);
  4153. $result = Braintree\Transaction::sale([
  4154. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4155. 'paymentMethodNonce' => $nonce,
  4156. 'paypalAccount' => [],
  4157. 'options' => [
  4158. 'paypal' => [
  4159. 'customField' => 'custom field stuff'
  4160. ]
  4161. ]
  4162. ]);
  4163. $this->assertTrue($result->success);
  4164. $transaction = $result->transaction;
  4165. $this->assertEquals('custom field stuff', $transaction->paypalDetails->customField);
  4166. $this->assertNotNull($transaction->paypalDetails->imageUrl);
  4167. $this->assertNotNull($transaction->paypalDetails->debugId);
  4168. $this->setExpectedException('Braintree\Exception\NotFound');
  4169. Braintree\PaymentMethod::find($paymentMethodToken);
  4170. }
  4171. public function testCreate_withPayPalSupplementaryData()
  4172. {
  4173. $paymentMethodToken = 'PAYPAL_TOKEN-' . strval(rand());
  4174. $http = new HttpClientApi(Braintree\Configuration::$global);
  4175. $nonce = $http->nonceForPayPalAccount([
  4176. 'paypal_account' => [
  4177. 'consent_code' => 'PAYPAL_CONSENT_CODE',
  4178. 'token' => $paymentMethodToken
  4179. ]
  4180. ]);
  4181. $result = Braintree\Transaction::sale([
  4182. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4183. 'paymentMethodNonce' => $nonce,
  4184. 'paypalAccount' => [],
  4185. 'options' => [
  4186. 'paypal' => [
  4187. 'supplementaryData' => [
  4188. 'key1' => 'value',
  4189. 'key2' => 'value'
  4190. ]
  4191. ]
  4192. ]
  4193. ]);
  4194. // note - supplementary data is not returned in response
  4195. $this->assertTrue($result->success);
  4196. }
  4197. public function testCreate_withPayPalDescription()
  4198. {
  4199. $paymentMethodToken = 'PAYPAL_TOKEN-' . strval(rand());
  4200. $http = new HttpClientApi(Braintree\Configuration::$global);
  4201. $nonce = $http->nonceForPayPalAccount([
  4202. 'paypal_account' => [
  4203. 'consent_code' => 'PAYPAL_CONSENT_CODE',
  4204. 'token' => $paymentMethodToken
  4205. ]
  4206. ]);
  4207. $result = Braintree\Transaction::sale([
  4208. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4209. 'paymentMethodNonce' => $nonce,
  4210. 'paypalAccount' => [],
  4211. 'options' => [
  4212. 'paypal' => [
  4213. 'description' => 'Product description'
  4214. ]
  4215. ]
  4216. ]);
  4217. $this->assertTrue($result->success);
  4218. $transaction = $result->transaction;
  4219. $this->assertEquals('Product description', $transaction->paypalDetails->description);
  4220. }
  4221. public function testCreate_withPayPalReturnsPaymentInstrumentType()
  4222. {
  4223. $paymentMethodToken = 'PAYPAL_TOKEN-' . strval(rand());
  4224. $http = new HttpClientApi(Braintree\Configuration::$global);
  4225. $nonce = $http->nonceForPayPalAccount([
  4226. 'paypal_account' => [
  4227. 'consent_code' => 'PAYPAL_CONSENT_CODE',
  4228. 'token' => $paymentMethodToken
  4229. ]
  4230. ]);
  4231. $result = Braintree\Transaction::sale([
  4232. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4233. 'paymentMethodNonce' => $nonce,
  4234. ]);
  4235. $this->assertTrue($result->success);
  4236. $transaction = $result->transaction;
  4237. $this->assertEquals(Braintree\PaymentInstrumentType::PAYPAL_ACCOUNT, $transaction->paymentInstrumentType);
  4238. $this->assertNotNull($transaction->paypalDetails->debugId);
  4239. }
  4240. public function testCreate_withFuturePayPalAndVault()
  4241. {
  4242. $paymentMethodToken = 'PAYPAL_TOKEN-' . strval(rand());
  4243. $http = new HttpClientApi(Braintree\Configuration::$global);
  4244. $nonce = $http->nonceForPayPalAccount([
  4245. 'paypal_account' => [
  4246. 'consent_code' => 'PAYPAL_CONSENT_CODE',
  4247. 'token' => $paymentMethodToken
  4248. ]
  4249. ]);
  4250. $result = Braintree\Transaction::sale([
  4251. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4252. 'paymentMethodNonce' => $nonce,
  4253. 'options' => [
  4254. 'storeInVault' => true
  4255. ]
  4256. ]);
  4257. $this->assertTrue($result->success);
  4258. $transaction = $result->transaction;
  4259. $this->assertEquals('payer@example.com', $transaction->paypalDetails->payerEmail);
  4260. $this->assertNotNull($transaction->paypalDetails->imageUrl);
  4261. $this->assertNotNull($transaction->paypalDetails->debugId);
  4262. $foundPayPalAccount = Braintree\PaymentMethod::find($paymentMethodToken);
  4263. $this->assertEquals($paymentMethodToken, $foundPayPalAccount->token);
  4264. }
  4265. public function testCreate_withOnetimePayPal()
  4266. {
  4267. $paymentMethodToken = 'PAYPAL_TOKEN-' . strval(rand());
  4268. $http = new HttpClientApi(Braintree\Configuration::$global);
  4269. $nonce = $http->nonceForPayPalAccount([
  4270. 'paypal_account' => [
  4271. 'access_token' => 'PAYPAL_ACCESS_TOKEN',
  4272. 'token' => $paymentMethodToken
  4273. ]
  4274. ]);
  4275. $result = Braintree\Transaction::sale([
  4276. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4277. 'paymentMethodNonce' => $nonce,
  4278. ]);
  4279. $this->assertTrue($result->success);
  4280. $transaction = $result->transaction;
  4281. $this->assertEquals('payer@example.com', $transaction->paypalDetails->payerEmail);
  4282. $this->assertNotNull($transaction->paypalDetails->imageUrl);
  4283. $this->assertNotNull($transaction->paypalDetails->debugId);
  4284. $this->setExpectedException('Braintree\Exception\NotFound');
  4285. Braintree\PaymentMethod::find($paymentMethodToken);
  4286. }
  4287. public function testCreate_withOnetimePayPalAndDoesNotVault()
  4288. {
  4289. $paymentMethodToken = 'PAYPAL_TOKEN-' . strval(rand());
  4290. $http = new HttpClientApi(Braintree\Configuration::$global);
  4291. $nonce = $http->nonceForPayPalAccount([
  4292. 'paypal_account' => [
  4293. 'access_token' => 'PAYPAL_ACCESS_TOKEN',
  4294. 'token' => $paymentMethodToken
  4295. ]
  4296. ]);
  4297. $result = Braintree\Transaction::sale([
  4298. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4299. 'paymentMethodNonce' => $nonce,
  4300. 'options' => [
  4301. 'storeInVault' => true
  4302. ]
  4303. ]);
  4304. $this->assertTrue($result->success);
  4305. $transaction = $result->transaction;
  4306. $this->assertEquals('payer@example.com', $transaction->paypalDetails->payerEmail);
  4307. $this->assertNotNull($transaction->paypalDetails->imageUrl);
  4308. $this->assertNotNull($transaction->paypalDetails->debugId);
  4309. $this->setExpectedException('Braintree\Exception\NotFound');
  4310. Braintree\PaymentMethod::find($paymentMethodToken);
  4311. }
  4312. public function testCreate_withPayPalAndSubmitForSettlement()
  4313. {
  4314. $nonce = Braintree\Test\Nonces::$paypalOneTimePayment;
  4315. $result = Braintree\Transaction::sale([
  4316. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4317. 'paymentMethodNonce' => $nonce,
  4318. 'options' => [
  4319. 'submitForSettlement' => true
  4320. ]
  4321. ]);
  4322. $this->assertTrue($result->success);
  4323. $transaction = $result->transaction;
  4324. $this->assertEquals(Braintree\Transaction::SETTLING, $transaction->status);
  4325. }
  4326. public function testCreate_withPayPalHandlesBadUnvalidatedNonces()
  4327. {
  4328. $http = new HttpClientApi(Braintree\Configuration::$global);
  4329. $nonce = $http->nonceForPayPalAccount([
  4330. 'paypal_account' => [
  4331. 'access_token' => 'PAYPAL_ACCESS_TOKEN',
  4332. 'consent_code' => 'PAYPAL_CONSENT_CODE'
  4333. ]
  4334. ]);
  4335. $result = Braintree\Transaction::sale([
  4336. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4337. 'paymentMethodNonce' => $nonce,
  4338. 'options' => [
  4339. 'submitForSettlement' => true
  4340. ]
  4341. ]);
  4342. $this->assertFalse($result->success);
  4343. $errors = $result->errors->forKey('transaction')->forKey('paypalAccount')->errors;
  4344. $this->assertEquals(Braintree\Error\Codes::PAYPAL_ACCOUNT_CANNOT_HAVE_BOTH_ACCESS_TOKEN_AND_CONSENT_CODE, $errors[0]->code);
  4345. }
  4346. public function testCreate_withPayPalHandlesNonExistentNonces()
  4347. {
  4348. $result = Braintree\Transaction::sale([
  4349. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4350. 'paymentMethodNonce' => 'NON_EXISTENT_NONCE',
  4351. 'options' => [
  4352. 'submitForSettlement' => true
  4353. ]
  4354. ]);
  4355. $this->assertFalse($result->success);
  4356. $errors = $result->errors->forKey('transaction')->errors;
  4357. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_PAYMENT_METHOD_NONCE_UNKNOWN, $errors[0]->code);
  4358. }
  4359. public function testVoid_withPayPal()
  4360. {
  4361. $nonce = Braintree\Test\Nonces::$paypalOneTimePayment;
  4362. $result = Braintree\Transaction::sale([
  4363. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4364. 'paymentMethodNonce' => $nonce
  4365. ]);
  4366. $this->assertTrue($result->success);
  4367. $voided_transaction = Braintree\Transaction::voidNoValidate($result->transaction->id);
  4368. $this->assertEquals(Braintree\Transaction::VOIDED, $voided_transaction->status);
  4369. }
  4370. public function testVoid_failsOnDeclinedPayPal()
  4371. {
  4372. $nonce = Braintree\Test\Nonces::$paypalOneTimePayment;
  4373. $result = Braintree\Transaction::sale([
  4374. 'amount' => Braintree\Test\TransactionAmounts::$decline,
  4375. 'paymentMethodNonce' => $nonce
  4376. ]);
  4377. $this->setExpectedException('Braintree\Exception\ValidationsFailed');
  4378. Braintree\Transaction::voidNoValidate($result->transaction->id);
  4379. }
  4380. public function testRefund_withPayPal()
  4381. {
  4382. $nonce = Braintree\Test\Nonces::$paypalOneTimePayment;
  4383. $transactionResult = Braintree\Transaction::sale([
  4384. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4385. 'paymentMethodNonce' => $nonce,
  4386. 'options' => [
  4387. 'submitForSettlement' => true
  4388. ]
  4389. ]);
  4390. $this->assertTrue($transactionResult->success);
  4391. Braintree\Test\Transaction::settle($transactionResult->transaction->id);
  4392. $result = Braintree\Transaction::refund($transactionResult->transaction->id);
  4393. $this->assertTrue($result->success);
  4394. $this->assertEquals($result->transaction->type, Braintree\Transaction::CREDIT);
  4395. }
  4396. public function testRefund_withPayPalAssignsRefundId()
  4397. {
  4398. $nonce = Braintree\Test\Nonces::$paypalOneTimePayment;
  4399. $transactionResult = Braintree\Transaction::sale([
  4400. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4401. 'paymentMethodNonce' => $nonce,
  4402. 'options' => [
  4403. 'submitForSettlement' => true
  4404. ]
  4405. ]);
  4406. $this->assertTrue($transactionResult->success);
  4407. $originalTransaction = $transactionResult->transaction;
  4408. Braintree\Test\Transaction::settle($transactionResult->transaction->id);
  4409. $result = Braintree\Transaction::refund($transactionResult->transaction->id);
  4410. $this->assertTrue($result->success);
  4411. $refundTransaction = $result->transaction;
  4412. $updatedOriginalTransaction = Braintree\Transaction::find($originalTransaction->id);
  4413. $this->assertEquals($refundTransaction->id, $updatedOriginalTransaction->refundId);
  4414. }
  4415. public function testRefund_withPayPalAssignsRefundedTransactionId()
  4416. {
  4417. $nonce = Braintree\Test\Nonces::$paypalOneTimePayment;
  4418. $transactionResult = Braintree\Transaction::sale([
  4419. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4420. 'paymentMethodNonce' => $nonce,
  4421. 'options' => [
  4422. 'submitForSettlement' => true
  4423. ]
  4424. ]);
  4425. $this->assertTrue($transactionResult->success);
  4426. $originalTransaction = $transactionResult->transaction;
  4427. Braintree\Test\Transaction::settle($transactionResult->transaction->id);
  4428. $result = Braintree\Transaction::refund($transactionResult->transaction->id);
  4429. $this->assertTrue($result->success);
  4430. $refundTransaction = $result->transaction;
  4431. $this->assertEquals($refundTransaction->refundedTransactionId, $originalTransaction->id);
  4432. }
  4433. public function testRefund_withPayPalFailsifAlreadyRefunded()
  4434. {
  4435. $nonce = Braintree\Test\Nonces::$paypalOneTimePayment;
  4436. $transactionResult = Braintree\Transaction::sale([
  4437. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4438. 'paymentMethodNonce' => $nonce,
  4439. 'options' => [
  4440. 'submitForSettlement' => true
  4441. ]
  4442. ]);
  4443. $this->assertTrue($transactionResult->success);
  4444. Braintree\Test\Transaction::settle($transactionResult->transaction->id);
  4445. $firstRefund = Braintree\Transaction::refund($transactionResult->transaction->id);
  4446. $this->assertTrue($firstRefund->success);
  4447. $secondRefund = Braintree\Transaction::refund($transactionResult->transaction->id);
  4448. $this->assertFalse($secondRefund->success);
  4449. $errors = $secondRefund->errors->forKey('transaction')->errors;
  4450. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_HAS_ALREADY_BEEN_REFUNDED, $errors[0]->code);
  4451. }
  4452. public function testRefund_withPayPalFailsIfNotSettled()
  4453. {
  4454. $nonce = Braintree\Test\Nonces::$paypalOneTimePayment;
  4455. $transactionResult = Braintree\Transaction::sale([
  4456. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4457. 'paymentMethodNonce' => $nonce,
  4458. ]);
  4459. $this->assertTrue($transactionResult->success);
  4460. $result = Braintree\Transaction::refund($transactionResult->transaction->id);
  4461. $this->assertFalse($result->success);
  4462. $errors = $result->errors->forKey('transaction')->errors;
  4463. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_CANNOT_REFUND_UNLESS_SETTLED, $errors[0]->code);
  4464. }
  4465. public function testRefund_partialWithPayPal()
  4466. {
  4467. $nonce = Braintree\Test\Nonces::$paypalOneTimePayment;
  4468. $transactionResult = Braintree\Transaction::sale([
  4469. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4470. 'paymentMethodNonce' => $nonce,
  4471. 'options' => [
  4472. 'submitForSettlement' => true
  4473. ]
  4474. ]);
  4475. $this->assertTrue($transactionResult->success);
  4476. Braintree\Test\Transaction::settle($transactionResult->transaction->id);
  4477. $result = Braintree\Transaction::refund(
  4478. $transactionResult->transaction->id,
  4479. $transactionResult->transaction->amount / 2
  4480. );
  4481. $this->assertTrue($result->success);
  4482. $this->assertEquals($result->transaction->type, Braintree\Transaction::CREDIT);
  4483. $this->assertEquals($result->transaction->amount, $transactionResult->transaction->amount / 2);
  4484. }
  4485. public function testRefund_multiplePartialWithPayPal()
  4486. {
  4487. $nonce = Braintree\Test\Nonces::$paypalOneTimePayment;
  4488. $transactionResult = Braintree\Transaction::sale([
  4489. 'amount' => Braintree\Test\TransactionAmounts::$authorize,
  4490. 'paymentMethodNonce' => $nonce,
  4491. 'options' => [
  4492. 'submitForSettlement' => true
  4493. ]
  4494. ]);
  4495. $this->assertTrue($transactionResult->success);
  4496. $originalTransaction = $transactionResult->transaction;
  4497. Braintree\Test\Transaction::settle($originalTransaction->id);
  4498. $firstRefund = Braintree\Transaction::refund(
  4499. $transactionResult->transaction->id,
  4500. $transactionResult->transaction->amount / 2
  4501. );
  4502. $this->assertTrue($firstRefund->success);
  4503. $firstRefundTransaction = $firstRefund->transaction;
  4504. $secondRefund = Braintree\Transaction::refund(
  4505. $transactionResult->transaction->id,
  4506. $transactionResult->transaction->amount / 2
  4507. );
  4508. $this->assertTrue($secondRefund->success);
  4509. $secondRefundTransaction = $secondRefund->transaction;
  4510. $updatedOriginalTransaction = Braintree\Transaction::find($originalTransaction->id);
  4511. $expectedRefundIds = [$secondRefundTransaction->id, $firstRefundTransaction->id];
  4512. $updatedRefundIds = $updatedOriginalTransaction->refundIds;
  4513. $this->assertTrue(in_array($expectedRefundIds[0],$updatedRefundIds));
  4514. $this->assertTrue(in_array($expectedRefundIds[1],$updatedRefundIds));
  4515. }
  4516. public function testIncludeProcessorSettlementResponseForSettlementDeclinedTransaction()
  4517. {
  4518. $result = Braintree\Transaction::sale([
  4519. "paymentMethodNonce" => Braintree\Test\Nonces::$visaCheckoutVisa,
  4520. "amount" => "100",
  4521. "options" => [
  4522. "submitForSettlement" => true
  4523. ]
  4524. ]);
  4525. $this->assertTrue($result->success);
  4526. $transaction = $result->transaction;
  4527. Braintree\Test\Transaction::settlementDecline($transaction->id);
  4528. $inline_transaction = Braintree\Transaction::find($transaction->id);
  4529. $this->assertEquals($inline_transaction->status, Braintree\Transaction::SETTLEMENT_DECLINED);
  4530. $this->assertEquals($inline_transaction->processorSettlementResponseCode, "4001");
  4531. $this->assertEquals($inline_transaction->processorSettlementResponseText, "Settlement Declined");
  4532. }
  4533. public function testIncludeProcessorSettlementResponseForSettlementPendingTransaction()
  4534. {
  4535. $result = Braintree\Transaction::sale([
  4536. "paymentMethodNonce" => Braintree\Test\Nonces::$visaCheckoutVisa,
  4537. "amount" => "100",
  4538. "options" => [
  4539. "submitForSettlement" => true
  4540. ]
  4541. ]);
  4542. $this->assertTrue($result->success);
  4543. $transaction = $result->transaction;
  4544. Braintree\Test\Transaction::settlementPending($transaction->id);
  4545. $inline_transaction = Braintree\Transaction::find($transaction->id);
  4546. $this->assertEquals($inline_transaction->status, Braintree\Transaction::SETTLEMENT_PENDING);
  4547. $this->assertEquals($inline_transaction->processorSettlementResponseCode, "4002");
  4548. $this->assertEquals($inline_transaction->processorSettlementResponseText, "Settlement Pending");
  4549. }
  4550. public function testSale_withLodgingIndustryData()
  4551. {
  4552. $result = Braintree\Transaction::sale([
  4553. 'amount' => '100.00',
  4554. 'creditCard' => [
  4555. 'number' => '5105105105105100',
  4556. 'expirationDate' => '05/12',
  4557. ],
  4558. 'industry' => [
  4559. 'industryType' => Braintree\Transaction::LODGING_INDUSTRY,
  4560. 'data' => [
  4561. 'folioNumber' => 'aaa',
  4562. 'checkInDate' => '2014-07-07',
  4563. 'checkOutDate' => '2014-07-09',
  4564. 'roomRate' => '239.00'
  4565. ]
  4566. ]
  4567. ]);
  4568. $this->assertTrue($result->success);
  4569. }
  4570. public function testSale_withLodgingIndustryDataValidation()
  4571. {
  4572. $result = Braintree\Transaction::sale([
  4573. 'amount' => '100.00',
  4574. 'creditCard' => [
  4575. 'number' => '5105105105105100',
  4576. 'expirationDate' => '05/12',
  4577. ],
  4578. 'industry' => [
  4579. 'industryType' => Braintree\Transaction::LODGING_INDUSTRY,
  4580. 'data' => [
  4581. 'folioNumber' => 'aaa',
  4582. 'checkInDate' => '2014-07-07',
  4583. 'checkOutDate' => '2014-06-09',
  4584. 'roomRate' => '239.00'
  4585. ]
  4586. ]
  4587. ]);
  4588. $this->assertFalse($result->success);
  4589. $transaction = $result->transaction;
  4590. $errors = $result->errors->forKey('transaction')->forKey('industry')->onAttribute('checkOutDate');
  4591. $this->assertEquals(Braintree\Error\Codes::INDUSTRY_DATA_LODGING_CHECK_OUT_DATE_MUST_FOLLOW_CHECK_IN_DATE, $errors[0]->code);
  4592. }
  4593. public function testSale_withTravelCruiseIndustryData()
  4594. {
  4595. $result = Braintree\Transaction::sale([
  4596. 'amount' => '100.00',
  4597. 'creditCard' => [
  4598. 'number' => '5105105105105100',
  4599. 'expirationDate' => '05/12',
  4600. ],
  4601. 'industry' => [
  4602. 'industryType' => Braintree\Transaction::TRAVEL_AND_CRUISE_INDUSTRY,
  4603. 'data' => [
  4604. 'travelPackage' => 'flight',
  4605. 'departureDate' => '2014-07-07',
  4606. 'lodgingCheckInDate' => '2014-07-09',
  4607. 'lodgingCheckOutDate' => '2014-07-10',
  4608. 'lodgingName' => 'Disney',
  4609. ]
  4610. ]
  4611. ]);
  4612. $this->assertTrue($result->success);
  4613. }
  4614. public function testSale_withTravelCruiseIndustryDataValidation()
  4615. {
  4616. $result = Braintree\Transaction::sale([
  4617. 'amount' => '100.00',
  4618. 'creditCard' => [
  4619. 'number' => '5105105105105100',
  4620. 'expirationDate' => '05/12',
  4621. ],
  4622. 'industry' => [
  4623. 'industryType' => Braintree\Transaction::TRAVEL_AND_CRUISE_INDUSTRY,
  4624. 'data' => [
  4625. 'travelPackage' => 'invalid',
  4626. 'departureDate' => '2014-07-07',
  4627. 'lodgingCheckInDate' => '2014-07-09',
  4628. 'lodgingCheckOutDate' => '2014-07-10',
  4629. 'lodgingName' => 'Disney',
  4630. ]
  4631. ]
  4632. ]);
  4633. $this->assertFalse($result->success);
  4634. $transaction = $result->transaction;
  4635. $errors = $result->errors->forKey('transaction')->forKey('industry')->onAttribute('travelPackage');
  4636. $this->assertEquals(Braintree\Error\Codes::INDUSTRY_DATA_TRAVEL_CRUISE_TRAVEL_PACKAGE_IS_INVALID, $errors[0]->code);
  4637. }
  4638. public function testSale_withAmexRewardsSucceeds()
  4639. {
  4640. $result = Braintree\Transaction::sale([
  4641. 'amount' => '47.00',
  4642. 'merchantAccountId' => Test\Helper::fakeAmexDirectMerchantAccountId(),
  4643. 'creditCard' => [
  4644. 'cardholderName' => 'The Cardholder',
  4645. 'number' => Braintree\Test\CreditCardNumbers::$amexPayWithPoints['Success'],
  4646. 'expirationDate' => '05/12'
  4647. ],
  4648. 'options' => [
  4649. 'submitForSettlement' => true,
  4650. 'amexRewards' => [
  4651. 'requestId' => 'ABC123',
  4652. 'points' => '100',
  4653. 'currencyAmount' => '1.00',
  4654. 'currencyIsoCode' => 'USD'
  4655. ]
  4656. ]
  4657. ]);
  4658. $this->assertTrue($result->success);
  4659. $transaction = $result->transaction;
  4660. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $transaction->status);
  4661. $this->assertEquals(Braintree\Transaction::SALE, $transaction->type);
  4662. }
  4663. public function testSale_withAmexRewardsSucceedsEvenIfCardIsIneligible()
  4664. {
  4665. $result = Braintree\Transaction::sale([
  4666. 'amount' => '47.00',
  4667. 'merchantAccountId' => Test\Helper::fakeAmexDirectMerchantAccountId(),
  4668. 'creditCard' => [
  4669. 'cardholderName' => 'The Cardholder',
  4670. 'number' => Braintree\Test\CreditCardNumbers::$amexPayWithPoints['IneligibleCard'],
  4671. 'expirationDate' => '05/12'
  4672. ],
  4673. 'options' => [
  4674. 'submitForSettlement' => true,
  4675. 'amexRewards' => [
  4676. 'requestId' => 'ABC123',
  4677. 'points' => '100',
  4678. 'currencyAmount' => '1.00',
  4679. 'currencyIsoCode' => 'USD'
  4680. ]
  4681. ]
  4682. ]);
  4683. $this->assertTrue($result->success);
  4684. $transaction = $result->transaction;
  4685. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $transaction->status);
  4686. $this->assertEquals(Braintree\Transaction::SALE, $transaction->type);
  4687. }
  4688. public function testSale_withAmexRewardsSucceedsEvenIfCardBalanceIsInsufficient()
  4689. {
  4690. $result = Braintree\Transaction::sale([
  4691. 'amount' => '47.00',
  4692. 'merchantAccountId' => Test\Helper::fakeAmexDirectMerchantAccountId(),
  4693. 'creditCard' => [
  4694. 'cardholderName' => 'The Cardholder',
  4695. 'number' => Braintree\Test\CreditCardNumbers::$amexPayWithPoints['InsufficientPoints'],
  4696. 'expirationDate' => '05/12'
  4697. ],
  4698. 'options' => [
  4699. 'submitForSettlement' => true,
  4700. 'amexRewards' => [
  4701. 'requestId' => 'ABC123',
  4702. 'points' => '100',
  4703. 'currencyAmount' => '1.00',
  4704. 'currencyIsoCode' => 'USD'
  4705. ]
  4706. ]
  4707. ]);
  4708. $this->assertTrue($result->success);
  4709. $transaction = $result->transaction;
  4710. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $transaction->status);
  4711. $this->assertEquals(Braintree\Transaction::SALE, $transaction->type);
  4712. }
  4713. public function testSubmitForSettlement_withAmexRewardsSucceeds()
  4714. {
  4715. $result = Braintree\Transaction::sale([
  4716. 'amount' => '47.00',
  4717. 'merchantAccountId' => Test\Helper::fakeAmexDirectMerchantAccountId(),
  4718. 'creditCard' => [
  4719. 'cardholderName' => 'The Cardholder',
  4720. 'number' => Braintree\Test\CreditCardNumbers::$amexPayWithPoints['Success'],
  4721. 'expirationDate' => '05/12'
  4722. ],
  4723. 'options' => [
  4724. 'amexRewards' => [
  4725. 'requestId' => 'ABC123',
  4726. 'points' => '100',
  4727. 'currencyAmount' => '1.00',
  4728. 'currencyIsoCode' => 'USD'
  4729. ]
  4730. ]
  4731. ]);
  4732. $this->assertTrue($result->success);
  4733. $transaction = $result->transaction;
  4734. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  4735. $this->assertEquals(Braintree\Transaction::SALE, $transaction->type);
  4736. $submitResult = Braintree\Transaction::submitForSettlement($transaction->id, '47.00');
  4737. $submitTransaction = $submitResult->transaction;
  4738. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $submitTransaction->status);
  4739. }
  4740. public function testSubmitForSettlement_withAmexRewardsSucceedsEvenIfCardIsIneligible()
  4741. {
  4742. $result = Braintree\Transaction::sale([
  4743. 'amount' => '47.00',
  4744. 'merchantAccountId' => Test\Helper::fakeAmexDirectMerchantAccountId(),
  4745. 'creditCard' => [
  4746. 'cardholderName' => 'The Cardholder',
  4747. 'number' => Braintree\Test\CreditCardNumbers::$amexPayWithPoints['IneligibleCard'],
  4748. 'expirationDate' => '05/12'
  4749. ],
  4750. 'options' => [
  4751. 'amexRewards' => [
  4752. 'requestId' => 'ABC123',
  4753. 'points' => '100',
  4754. 'currencyAmount' => '1.00',
  4755. 'currencyIsoCode' => 'USD'
  4756. ]
  4757. ]
  4758. ]);
  4759. $this->assertTrue($result->success);
  4760. $transaction = $result->transaction;
  4761. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  4762. $this->assertEquals(Braintree\Transaction::SALE, $transaction->type);
  4763. $submitResult = Braintree\Transaction::submitForSettlement($transaction->id, '47.00');
  4764. $submitTransaction = $submitResult->transaction;
  4765. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $submitTransaction->status);
  4766. }
  4767. public function testSubmitForSettlement_withAmexRewardsSucceedsEvenIfCardBalanceIsInsufficient()
  4768. {
  4769. $result = Braintree\Transaction::sale([
  4770. 'amount' => '47.00',
  4771. 'merchantAccountId' => Test\Helper::fakeAmexDirectMerchantAccountId(),
  4772. 'creditCard' => [
  4773. 'cardholderName' => 'The Cardholder',
  4774. 'number' => Braintree\Test\CreditCardNumbers::$amexPayWithPoints['InsufficientPoints'],
  4775. 'expirationDate' => '05/12'
  4776. ],
  4777. 'options' => [
  4778. 'amexRewards' => [
  4779. 'requestId' => 'ABC123',
  4780. 'points' => '100',
  4781. 'currencyAmount' => '1.00',
  4782. 'currencyIsoCode' => 'USD'
  4783. ]
  4784. ]
  4785. ]);
  4786. $this->assertTrue($result->success);
  4787. $transaction = $result->transaction;
  4788. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  4789. $this->assertEquals(Braintree\Transaction::SALE, $transaction->type);
  4790. $submitResult = Braintree\Transaction::submitForSettlement($transaction->id, '47.00');
  4791. $submitTransaction = $submitResult->transaction;
  4792. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $submitTransaction->status);
  4793. }
  4794. public function testSubmitForPartialSettlement()
  4795. {
  4796. $authorizedTransaction = Braintree\Transaction::saleNoValidate([
  4797. 'amount' => '100.00',
  4798. 'creditCard' => [
  4799. 'number' => '5105105105105100',
  4800. 'expirationDate' => '05/12'
  4801. ]
  4802. ]);
  4803. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $authorizedTransaction->status);
  4804. $partialSettlementResult1 = Braintree\Transaction::submitForPartialSettlement($authorizedTransaction->id, '60.00');
  4805. $this->assertTrue($partialSettlementResult1->success);
  4806. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $partialSettlementResult1->transaction->status);
  4807. $this->assertEquals('60.00', $partialSettlementResult1->transaction->amount);
  4808. $partialSettlementResult2 = Braintree\Transaction::submitForPartialSettlement($authorizedTransaction->id, '40.00');
  4809. $this->assertTrue($partialSettlementResult2->success);
  4810. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $partialSettlementResult2->transaction->status);
  4811. $this->assertEquals('40.00', $partialSettlementResult2->transaction->amount);
  4812. $refreshedAuthorizedTransaction = Braintree\Transaction::find($authorizedTransaction->id);
  4813. $this->assertEquals(2, count($refreshedAuthorizedTransaction->partialSettlementTransactionIds));
  4814. }
  4815. public function testSubmitForPartialSettlementUnsuccesful()
  4816. {
  4817. $authorizedTransaction = Braintree\Transaction::saleNoValidate([
  4818. 'amount' => '100.00',
  4819. 'creditCard' => [
  4820. 'number' => '5105105105105100',
  4821. 'expirationDate' => '05/12'
  4822. ]
  4823. ]);
  4824. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $authorizedTransaction->status);
  4825. $partialSettlementResult1 = Braintree\Transaction::submitForPartialSettlement($authorizedTransaction->id, '60.00');
  4826. $this->assertTrue($partialSettlementResult1->success);
  4827. $partialSettlementResult2 = Braintree\Transaction::submitForPartialSettlement($partialSettlementResult1->transaction->id, '10.00');
  4828. $this->assertFalse($partialSettlementResult2->success);
  4829. $baseErrors = $partialSettlementResult2->errors->forKey('transaction')->onAttribute('base');
  4830. $this->assertEquals(Braintree\Error\Codes::TRANSACTION_CANNOT_SUBMIT_FOR_PARTIAL_SETTLEMENT, $baseErrors[0]->code);
  4831. }
  4832. public function testSubmitForPartialSettlement_withOrderId()
  4833. {
  4834. $transaction = Braintree\Transaction::saleNoValidate([
  4835. 'amount' => '100.00',
  4836. 'creditCard' => [
  4837. 'number' => '5105105105105100',
  4838. 'expirationDate' => '05/12'
  4839. ]
  4840. ]);
  4841. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  4842. $submitResult = Braintree\Transaction::submitForPartialSettlement($transaction->id, '67.00', ['orderId' => 'ABC123']);
  4843. $this->assertEquals(true, $submitResult->success);
  4844. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $submitResult->transaction->status);
  4845. $this->assertEquals('ABC123', $submitResult->transaction->orderId);
  4846. $this->assertEquals('67.00', $submitResult->transaction->amount);
  4847. }
  4848. public function testSubmitForPartialSettlement_withDescriptor()
  4849. {
  4850. $transaction = Braintree\Transaction::saleNoValidate([
  4851. 'amount' => '100.00',
  4852. 'creditCard' => [
  4853. 'number' => '5105105105105100',
  4854. 'expirationDate' => '05/12'
  4855. ]
  4856. ]);
  4857. $params = [
  4858. 'descriptor' => [
  4859. 'name' => '123*123456789012345678',
  4860. 'phone' => '3334445555',
  4861. 'url' => 'ebay.com'
  4862. ]
  4863. ];
  4864. $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transaction->status);
  4865. $submitResult = Braintree\Transaction::submitForPartialSettlement($transaction->id, '67.00', $params);
  4866. $this->assertEquals(true, $submitResult->success);
  4867. $this->assertEquals(Braintree\Transaction::SUBMITTED_FOR_SETTLEMENT, $submitResult->transaction->status);
  4868. $this->assertEquals('123*123456789012345678', $submitResult->transaction->descriptor->name);
  4869. $this->assertEquals('3334445555', $submitResult->transaction->descriptor->phone);
  4870. $this->assertEquals('ebay.com', $submitResult->transaction->descriptor->url);
  4871. }
  4872. public function testSubmitForPartialSettlement_withInvalidParams()
  4873. {
  4874. $transaction = Braintree\Transaction::saleNoValidate([
  4875. 'amount' => '100.00',
  4876. 'creditCard' => [
  4877. 'number' => '5105105105105100',
  4878. 'expirationDate' => '05/12'
  4879. ]
  4880. ]);
  4881. $params = ['invalid' => 'invalid'];
  4882. $this->setExpectedException('InvalidArgumentException', 'invalid keys: invalid');
  4883. Braintree\Transaction::submitForPartialSettlement($transaction->id, '67.00', $params);
  4884. }
  4885. public function testFacilitatedAndFacilitatorDetailsAreReturnedOnTransactionsCreatedViaNonceGranting()
  4886. {
  4887. $partnerMerchantGateway = new Braintree\Gateway([
  4888. 'environment' => 'development',
  4889. 'merchantId' => 'integration_merchant_public_id',
  4890. 'publicKey' => 'oauth_app_partner_user_public_key',
  4891. 'privateKey' => 'oauth_app_partner_user_private_key'
  4892. ]);
  4893. $customer = $partnerMerchantGateway->customer()->create([
  4894. 'firstName' => 'Joe',
  4895. 'lastName' => 'Brown'
  4896. ])->customer;
  4897. $creditCard = $partnerMerchantGateway->creditCard()->create([
  4898. 'customerId' => $customer->id,
  4899. 'cardholderName' => 'Adam Davis',
  4900. 'number' => '4111111111111111',
  4901. 'expirationDate' => '05/2009'
  4902. ])->creditCard;
  4903. $oauthAppGateway = new Braintree\Gateway([
  4904. 'clientId' => 'client_id$development$integration_client_id',
  4905. 'clientSecret' => 'client_secret$development$integration_client_secret'
  4906. ]);
  4907. $code = Test\Braintree\OAuthTestHelper::createGrant($oauthAppGateway, [
  4908. 'merchant_public_id' => 'integration_merchant_id',
  4909. 'scope' => 'grant_payment_method'
  4910. ]);
  4911. $credentials = $oauthAppGateway->oauth()->createTokenFromCode([
  4912. 'code' => $code,
  4913. ]);
  4914. $grantingGateway = new Braintree\Gateway([
  4915. 'accessToken' => $credentials->accessToken
  4916. ]);
  4917. $grantResult = $grantingGateway->paymentMethod()->grant($creditCard->token, false);
  4918. $result = Braintree\Transaction::sale([
  4919. 'amount' => '100.00',
  4920. 'paymentMethodNonce' => $grantResult->paymentMethodNonce->nonce
  4921. ]);
  4922. $this->assertEquals(
  4923. $result->transaction->facilitatedDetails->merchantId,
  4924. 'integration_merchant_id'
  4925. );
  4926. $this->assertEquals(
  4927. $result->transaction->facilitatedDetails->merchantName,
  4928. '14ladders'
  4929. );
  4930. $this->assertEquals(
  4931. $result->transaction->facilitatedDetails->paymentMethodNonce,
  4932. $grantResult->paymentMethodNonce->nonce
  4933. );
  4934. $this->assertEquals(
  4935. $result->transaction->facilitatorDetails->oauthApplicationClientId,
  4936. "client_id\$development\$integration_client_id"
  4937. );
  4938. $this->assertEquals(
  4939. $result->transaction->facilitatorDetails->oauthApplicationName,
  4940. "PseudoShop"
  4941. );
  4942. $this->assertNull($result->transaction->billing["postalCode"]);
  4943. }
  4944. public function testBillingPostalCodeIsReturnedWhenRequestedOnTransactionsCreatedViaNonceGranting()
  4945. {
  4946. $partnerMerchantGateway = new Braintree\Gateway([
  4947. 'environment' => 'development',
  4948. 'merchantId' => 'integration_merchant_public_id',
  4949. 'publicKey' => 'oauth_app_partner_user_public_key',
  4950. 'privateKey' => 'oauth_app_partner_user_private_key'
  4951. ]);
  4952. $customer = $partnerMerchantGateway->customer()->create([
  4953. 'firstName' => 'Joe',
  4954. 'lastName' => 'Brown'
  4955. ])->customer;
  4956. $creditCard = $partnerMerchantGateway->creditCard()->create([
  4957. 'customerId' => $customer->id,
  4958. 'cardholderName' => 'Adam Davis',
  4959. 'number' => '4111111111111111',
  4960. 'expirationDate' => '05/2009',
  4961. 'billingAddress' => [
  4962. 'firstName' => 'Adam',
  4963. 'lastName' => 'Davis',
  4964. 'postalCode' => '95131'
  4965. ]
  4966. ])->creditCard;
  4967. $oauthAppGateway = new Braintree\Gateway([
  4968. 'clientId' => 'client_id$development$integration_client_id',
  4969. 'clientSecret' => 'client_secret$development$integration_client_secret'
  4970. ]);
  4971. $code = Test\Braintree\OAuthTestHelper::createGrant($oauthAppGateway, [
  4972. 'merchant_public_id' => 'integration_merchant_id',
  4973. 'scope' => 'grant_payment_method'
  4974. ]);
  4975. $credentials = $oauthAppGateway->oauth()->createTokenFromCode([
  4976. 'code' => $code,
  4977. ]);
  4978. $grantingGateway = new Braintree\Gateway([
  4979. 'accessToken' => $credentials->accessToken
  4980. ]);
  4981. $grantResult = $grantingGateway->paymentMethod()->grant($creditCard->token, ['allow_vaulting' => false, 'include_billing_postal_code' => true]);
  4982. $result = Braintree\Transaction::sale([
  4983. 'amount' => '100.00',
  4984. 'paymentMethodNonce' => $grantResult->paymentMethodNonce->nonce
  4985. ]);
  4986. $this->assertEquals($result->transaction->billing["postalCode"], "95131");
  4987. }
  4988. public function testTransactionsCanBeCreatedWithSharedPaymentMethodToken()
  4989. {
  4990. $partnerMerchantGateway = new Braintree\Gateway([
  4991. 'environment' => 'development',
  4992. 'merchantId' => 'integration_merchant_public_id',
  4993. 'publicKey' => 'oauth_app_partner_user_public_key',
  4994. 'privateKey' => 'oauth_app_partner_user_private_key'
  4995. ]);
  4996. $customer = $partnerMerchantGateway->customer()->create([
  4997. 'firstName' => 'Joe',
  4998. 'lastName' => 'Brown'
  4999. ])->customer;
  5000. $address = $partnerMerchantGateway->address()->create([
  5001. 'customerId' => $customer->id,
  5002. 'firstName' => 'Dan',
  5003. 'lastName' => 'Smith',
  5004. ])->address;
  5005. $creditCard = $partnerMerchantGateway->creditCard()->create([
  5006. 'customerId' => $customer->id,
  5007. 'cardholderName' => 'Adam Davis',
  5008. 'number' => '4111111111111111',
  5009. 'expirationDate' => '05/2009'
  5010. ])->creditCard;
  5011. $oauthAppGateway = new Braintree\Gateway([
  5012. 'clientId' => 'client_id$development$integration_client_id',
  5013. 'clientSecret' => 'client_secret$development$integration_client_secret'
  5014. ]);
  5015. $code = Test\Braintree\OAuthTestHelper::createGrant($oauthAppGateway, [
  5016. 'merchant_public_id' => 'integration_merchant_id',
  5017. 'scope' => 'read_write,shared_vault_transactions'
  5018. ]);
  5019. $credentials = $oauthAppGateway->oauth()->createTokenFromCode([
  5020. 'code' => $code,
  5021. ]);
  5022. $oauthAccesTokenGateway = new Braintree\Gateway([
  5023. 'accessToken' => $credentials->accessToken
  5024. ]);
  5025. $result = $oauthAccesTokenGateway->transaction()->sale([
  5026. 'amount' => '100.00',
  5027. 'sharedPaymentMethodToken' => $creditCard->token,
  5028. 'sharedCustomerId' => $customer->id,
  5029. 'sharedShippingAddressId' => $address->id,
  5030. 'sharedBillingAddressId' => $address->id
  5031. ]);
  5032. $this->assertEquals(
  5033. $result->transaction->shippingDetails->firstName,
  5034. $address->firstName
  5035. );
  5036. $this->assertEquals(
  5037. $result->transaction->billingDetails->firstName,
  5038. $address->firstName
  5039. );
  5040. }
  5041. public function testTransactionsCanBeCreatedWithSharedPaymentMethodNonce()
  5042. {
  5043. $partnerMerchantGateway = new Braintree\Gateway([
  5044. 'environment' => 'development',
  5045. 'merchantId' => 'integration_merchant_public_id',
  5046. 'publicKey' => 'oauth_app_partner_user_public_key',
  5047. 'privateKey' => 'oauth_app_partner_user_private_key'
  5048. ]);
  5049. $customer = $partnerMerchantGateway->customer()->create([
  5050. 'firstName' => 'Joe',
  5051. 'lastName' => 'Brown'
  5052. ])->customer;
  5053. $address = $partnerMerchantGateway->address()->create([
  5054. 'customerId' => $customer->id,
  5055. 'firstName' => 'Dan',
  5056. 'lastName' => 'Smith',
  5057. ])->address;
  5058. $creditCard = $partnerMerchantGateway->creditCard()->create([
  5059. 'customerId' => $customer->id,
  5060. 'cardholderName' => 'Adam Davis',
  5061. 'number' => '4111111111111111',
  5062. 'expirationDate' => '05/2009'
  5063. ])->creditCard;
  5064. $oauthAppGateway = new Braintree\Gateway([
  5065. 'clientId' => 'client_id$development$integration_client_id',
  5066. 'clientSecret' => 'client_secret$development$integration_client_secret'
  5067. ]);
  5068. $code = Test\Braintree\OAuthTestHelper::createGrant($oauthAppGateway, [
  5069. 'merchant_public_id' => 'integration_merchant_id',
  5070. 'scope' => 'read_write,shared_vault_transactions'
  5071. ]);
  5072. $credentials = $oauthAppGateway->oauth()->createTokenFromCode([
  5073. 'code' => $code,
  5074. ]);
  5075. $oauthAccesTokenGateway = new Braintree\Gateway([
  5076. 'accessToken' => $credentials->accessToken
  5077. ]);
  5078. $sharedNonce = $partnerMerchantGateway->paymentMethodNonce()->create(
  5079. $creditCard->token
  5080. )->paymentMethodNonce->nonce;
  5081. $result = $oauthAccesTokenGateway->transaction()->sale([
  5082. 'amount' => '100.00',
  5083. 'sharedPaymentMethodNonce' => $sharedNonce,
  5084. 'sharedCustomerId' => $customer->id,
  5085. 'sharedShippingAddressId' => $address->id,
  5086. 'sharedBillingAddressId' => $address->id
  5087. ]);
  5088. $this->assertEquals(
  5089. $result->transaction->shippingDetails->firstName,
  5090. $address->firstName
  5091. );
  5092. $this->assertEquals(
  5093. $result->transaction->billingDetails->firstName,
  5094. $address->firstName
  5095. );
  5096. }
  5097. }