![]() | ![]() Products ![]() ![]() ![]() ![]() |
Home » Technical Support » Elevate Web Builder Technical Support » Support Forums » Elevate Web Builder General » View Thread |
Messages 1 to 10 of 18 total |
![]() |
Thu, Mar 20 2014 12:56 PM | Permanent Link |
Matthew Jones | I'd just like to say, while I'm feeling happy, that writing web systems in Elevate
WebBuilder is really good fun. I've just done my first complete "3D-Secure" (Verified by Visa) transaction on my new web shop. The WebBuilder part is sort of easy, but it sends the order details to my Delphi backend, which is using RemObjects SDK as the communication mechanism. The Delphi back-end does all sorts of things like generate install codes for the software, create PDF invoices, and sends emails. These are done in threads, which watch DBISAM tables for things to do, which means that the EWB application in the browser sends the request and then asks for the status to show the customer and it keeps it responsive. The actual card payment is done using another service dedicated to talking to the card processing company. The link is again via RemObjects, but with an interface DLL to make it easy for a desktop app. In the case of the 3D Secure requirement, the card service returns data which is returned to the EWB application to trigger the TPage to show the authentication page. They authenticate, and that causes a POST to the RemObjects server which I customised to take the data and pass it to the database and then kick the order processing thread along which then passes the data back to the card service, which then completes the payment. Then the order is completed and the user gets to see the final cart. I wrote the whole product selection and cart thing in about 2.5 weeks. The 3D secure part was about 2 weeks I think. I did start with my existing service framework and card system, but I have implemented a new provider. All been really good fun and little hassle. I shall soon ask for feedback on it... /Matthew Jones/ |
Fri, Mar 21 2014 5:22 AM | Permanent Link |
Mark Brooks Slikware | Would like to see this Matthew
|
Fri, Mar 21 2014 9:35 AM | Permanent Link |
Matthew Jones | There's an early version at dev .ban xia. com (eliminate the spaces to access!
I'll be updating it with the much better version sometime next week. Feel free to create an account. I shall work out a way to hide the test card numbers sometime but in that version any 16 digit number "works" I think. /Matthew Jones/ |
Fri, Mar 21 2014 10:46 AM | Permanent Link |
Matthew Jones | I've set up "demo@ ban
xia . com" with the password elevate. I've also set the card payment to test mode so it isn't doing anything real (it never will, but this doesn't even talk to anyone either). /Matthew Jones/ |
Tue, Mar 25 2014 12:36 PM | Permanent Link |
Matthew Jones | I'd be interested in any feedback on this. I've not yet got it polished, and the
shipping and tax is "todo" but it is now up to date and working. Details of a test card number are at the bottom of the application, and it does the full "verified by VISA" operation, except it is with the test card of my payment provider so it looks all technical - just hit "submit" to complete. The invoice download works, the software install codes are not complete and you can't download, but I'm quite pleased with it so far. (Most of the last week has been fighting the payment provider - integrating it into EWB has been easy). Account details in the previous posting, and it may change in the future. /Matthew Jones/ |
Thu, Mar 27 2014 6:53 AM | Permanent Link |
Mark Brooks Slikware | >> I'd be interested in any feedback on this.
It's nice Mathew. Only slight concern for me would be lack of distinct "view URLs" and therefore ability to navigate with browser back and forward. Great job though. |
Thu, Mar 27 2014 9:35 AM | Permanent Link |
Matthew Jones | Browser navigation is an interesting one - it doesn't look too possible. But it
does make me think that it needs to have a few "jump to product" facilities so that we can link directly to a specific product. Hmm, slight issue in that the products come from a database, but I'll work on that too! It's not finished, but it is getting there. /Matthew Jones/ |
Thu, Mar 27 2014 4:24 PM | Permanent Link |
Mark Brooks Slikware | >> Browser navigation is an interesting one - it doesn't look too possible
It's pretty straightforward if you: 1) Define a number of views in your app e.g. Login 2) Define a URL hash string for each e.g. #View=Login 3) Have your code set the URL has string in order to display a particular view 4) Trap the hash change and show the view accordingly Sounds a lot, but actually not too much code Cheers |
Fri, Mar 28 2014 6:29 AM | Permanent Link |
Matthew Jones | Do you have code for EWB to do it? I'll give it a go if you have.
/Matthew Jones/ |
Wed, Apr 2 2014 6:25 AM | Permanent Link |
Mark Brooks Slikware | >>Do you have code for EWB to do it? I'll give it a go if you have.
SO SORRY for the delay, but hope this makes sense // Call this in order to trap changes to the "hash" part of the URL SetWindowEventHandler('hashchange',TrapWindowHashChange); // Code a bit like this will form the trap function TfrmHeader.TrapWindowHashChange(event: TEvent): boolean; begin Result := True; fWindowHash.ReadFromBrowser; if fWindowHash.Names[0] = 'View' then begin if fWindowHash.Values[0] = 'Home' then DoShowForm(frmHome) else if fWindowHash.Values[0] = 'Welcome' then DoShowForm(frmWelcome) else if fWindowHash.Values[0] = 'Item' then DoShowForm(frmItem) else if fWindowHash.Values[0] = 'Preview' then DoShowForm(frmPreview) else if fWindowHash.Values[0] = 'Folder' then DoShowForm(frmFolder) else if fWindowHash.Values[0] = 'Notifications' then DoShowForm(frmNotifications) else if fWindowHash.Values[0] = 'Discussions' then DoShowForm(frmDiscussions) else if fWindowHash.Values[0] = 'Subscribed' then DoShowForm(frmSubscribed) else if fWindowHash.Values[0] = 'Upload' then DoShowForm(frmUpload) else if fWindowHash.Values[0] = 'Settings' then DoShowForm(frmSettings) else if fWindowHash.Values[0] = 'Search' then DoShowForm(frmSearch) else if fWindowHash.Values[0] = 'Discussion' then DoShowForm(frmDiscussion) end end; // And I have a class to read and write the "hash" element of the URL (fWindowHash in the above code) including breaking out name:value pairs TWindowHash = class private fList: TStringList; function GetText: string; function GetCount: integer; function GetName(I: integer): string; function GetValue(I: integer): string; public constructor Create; override; destructor Destroy; override; procedure Clear; procedure SendToBrowser(const ANewTab: boolean = False); procedure ReadFromBrowser; procedure AddPair(const AName: string; const AValue: string); property Count: integer read GetCount; property Names[I: integer]: string read GetName; property Values[I: integer]: string read GetValue; property Text: string read GetText; end; implementation uses WebDOM; constructor TWindowHash.Create; begin inherited Create; fList := TStringList.Create; fList.LineSeparator := '&'; end; destructor TWindowhash.Destroy; begin fList.Free; inherited Destroy; end; procedure TWindowHash.SendToBrowser(const ANewTab: boolean = False); var S: string; I: integer; begin if fList.Count = 0 then S := '' else begin S := '#'; for I := 0 to fList.Count - 1 do begin S := S + Names[I]; S := S + '='; S := S + Values[I]; if I < fList.Count - 1 then S := S + '&'; end; end; if ANewTab then Window.Open(StrReplace(Window.Location.HRef,Window.Location.Hash,S),'_blank','',False) else Window.Location.Hash := S; {+ '&_dc=' + IntToStr(MSecondOf(Now) + (SecondOf(Now) * 1000) + (MinuteOf(Now) * 60 * 1000))} end; procedure TWindowHash.ReadFromBrowser; var S: string; I: integer; begin fList.Clear; S := Window.Location.Hash; if S[1] <> '#' then exit; S := Copy(S,2,Length(S) - 1); if S = '' then raise EError.Create('TWindowHash.ReadFromBrowser: Empty hash encountered'); fList.Text := S; for I := 0 to fList.Count - 1 do if Pos('=',fList[I]) = 0 then raise EError.Create('TWindowHash.ReadFromBrowser: Pair format is invalid'); {if Pos('_dc=',fList[fList.Count - 1]) <> 0 then fList.Remove(fList.Count - 1);} end; procedure TWindowHash.Clear; begin fList.Clear; end; procedure TWindowHash.AddPair(const AName: string; const AValue: string); begin if Trim(AName) = '' then raise EError.Create('TWindowHash.AddPair: Empty name'); if Trim(AValue) = '' then raise EError.Create('TWindowHash.AddPair: Empty value'); fList.Add(Trim(AName) + '=' + Trim(AValue)); end; function TWindowHash.GetText: string; begin Result := fList.Text; end; function TWindowHash.GetCount: integer; begin Result := fList.Count; end; function TWindowHash.GetName(I: integer): string; var S: string; P: integer; begin if (I < 0) or (I > fList.Count - 1) then raise EError.Create('TWindowHash.GetName: Invalid index'); S := fList[I]; P := Pos('=',S); if P = 0 then raise EError.Create('TWindowHash.GetName: Pair format is invalid'); Result := Copy(S,1,P - 1); if Result = '' then raise EError.Create('TWindowHash.GetName: Empty name'); end; function TWindowHash.GetValue(I: integer): string; var S: string; P: integer; begin if (I < 0) or (I > fList.Count - 1) then raise EError.Create('TWindowHash.GetValue: Invalid index'); S := fList[I]; P := Pos('=',S); if P = 0 then raise EError.Create('TWindowHash.GetValue: Pair format is invalid'); Result := Copy(S,P + 1,Length(S) - P); if Result = '' then raise EError.Create('TWindowHash.GetValue: Empty value'); end; |
Page 1 of 2 | Next Page » | |
Jump to Page: 1 2 |
This web page was last updated on Friday, March 17, 2023 at 10:08 PM | Privacy Policy![]() © 2023 Elevate Software, Inc. All Rights Reserved Questions or comments ? ![]() |